http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java new file mode 100644 index 0000000..3551a80 --- /dev/null +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java @@ -0,0 +1,663 @@ +/* + * 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.provisioning.java.data; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.common.lib.SyncopeClientCompositeException; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.mod.AnyMod; +import org.apache.syncope.common.lib.mod.AttrMod; +import org.apache.syncope.common.lib.to.AnyTO; +import org.apache.syncope.common.lib.to.AttrTO; +import org.apache.syncope.common.lib.types.ClientExceptionType; +import org.apache.syncope.common.lib.types.IntMappingType; +import org.apache.syncope.common.lib.types.MappingPurpose; +import org.apache.syncope.common.lib.types.ResourceOperation; +import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException; +import org.apache.syncope.core.persistence.api.dao.DerAttrDAO; +import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; +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.PlainAttrValueDAO; +import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; +import org.apache.syncope.core.persistence.api.dao.PolicyDAO; +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.VirSchemaDAO; +import org.apache.syncope.core.persistence.api.entity.DerAttr; +import org.apache.syncope.core.persistence.api.entity.DerSchema; +import org.apache.syncope.core.persistence.api.entity.EntityFactory; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; +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.VirAttr; +import org.apache.syncope.core.persistence.api.entity.VirSchema; +import org.apache.syncope.core.persistence.api.entity.group.Group; +import org.apache.syncope.common.lib.types.PropagationByResource; +import org.apache.syncope.core.provisioning.java.VirAttrHandler; +import org.apache.syncope.core.misc.MappingUtils; +import org.apache.syncope.core.misc.jexl.JexlUtils; +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.RealmDAO; +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.AnyUtilsFactory; +import org.apache.syncope.core.persistence.api.entity.Realm; +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.resource.MappingItem; +import org.apache.syncope.core.persistence.api.entity.resource.Provision; +import org.apache.syncope.core.persistence.api.entity.user.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +abstract class AbstractAnyDataBinder { + + protected static final Logger LOG = LoggerFactory.getLogger(AbstractAnyDataBinder.class); + + @Autowired + protected RealmDAO realmDAO; + + @Autowired + protected AnyObjectDAO anyObjectDAO; + + @Autowired + protected UserDAO userDAO; + + @Autowired + protected GroupDAO groupDAO; + + @Autowired + protected PlainSchemaDAO plainSchemaDAO; + + @Autowired + protected DerSchemaDAO derSchemaDAO; + + @Autowired + protected VirSchemaDAO virSchemaDAO; + + @Autowired + protected PlainAttrDAO plainAttrDAO; + + @Autowired + protected DerAttrDAO derAttrDAO; + + @Autowired + protected VirAttrDAO virAttrDAO; + + @Autowired + protected PlainAttrValueDAO plainAttrValueDAO; + + @Autowired + protected ExternalResourceDAO resourceDAO; + + @Autowired + protected PolicyDAO policyDAO; + + @Autowired + protected EntityFactory entityFactory; + + @Autowired + protected AnyUtilsFactory anyUtilsFactory; + + @Autowired + protected VirAttrHandler virtAttrHander; + + protected void setRealm(final Any<?, ?, ?> any, final AnyMod anyMod) { + if (StringUtils.isNotBlank(anyMod.getRealm())) { + Realm newRealm = realmDAO.find(anyMod.getRealm()); + if (newRealm == null) { + LOG.warn("Invalid realm specified: {}, ignoring", anyMod.getRealm()); + } else { + any.setRealm(newRealm); + } + } + } + + protected PlainSchema getPlainSchema(final String schemaName) { + PlainSchema schema = null; + if (StringUtils.isNotBlank(schemaName)) { + schema = plainSchemaDAO.find(schemaName); + + // safely ignore invalid schemas from AttrTO + if (schema == null) { + LOG.debug("Ignoring invalid schema {}", schemaName); + } else if (schema.isReadonly()) { + schema = null; + + LOG.debug("Ignoring readonly schema {}", schemaName); + } + } + + return schema; + } + + private DerSchema getDerSchema(final String derSchemaName) { + DerSchema schema = null; + if (StringUtils.isNotBlank(derSchemaName)) { + schema = derSchemaDAO.find(derSchemaName); + if (schema == null) { + LOG.debug("Ignoring invalid derived schema {}", derSchemaName); + } + } + + return schema; + } + + protected void fillAttribute(final List<String> values, final AnyUtils anyUtils, + final PlainSchema schema, final PlainAttr<?> attr, final SyncopeClientException invalidValues) { + + // if schema is multivalue, all values are considered for addition; + // otherwise only the fist one - if provided - is considered + List<String> valuesProvided = schema.isMultivalue() + ? values + : (values.isEmpty() + ? Collections.<String>emptyList() + : Collections.singletonList(values.iterator().next())); + + for (String value : valuesProvided) { + if (value == null || value.isEmpty()) { + LOG.debug("Null value for {}, ignoring", schema.getKey()); + } else { + try { + attr.add(value, anyUtils); + } catch (InvalidPlainAttrValueException e) { + LOG.warn("Invalid value for attribute " + schema.getKey() + ": " + value, e); + + invalidValues.getElements().add(schema.getKey() + ": " + value + " - " + e.getMessage()); + } + } + } + } + + private boolean evaluateMandatoryCondition(final AnyUtils anyUtils, final ExternalResource resource, + final Any<?, ?, ?> any, final String intAttrName, final IntMappingType intMappingType) { + + boolean result = false; + + Collection<MappingItem> mappings = MappingUtils.getMatchingMappingItems( + anyUtils.getMappingItems(resource.getProvision(any.getType()), MappingPurpose.PROPAGATION), + intAttrName, intMappingType); + for (Iterator<MappingItem> itor = mappings.iterator(); itor.hasNext() && !result;) { + MappingItem mapping = itor.next(); + result |= JexlUtils.evaluateMandatoryCondition(mapping.getMandatoryCondition(), any); + } + + return result; + } + + private boolean evaluateMandatoryCondition(final AnyUtils anyUtils, + final Any<?, ?, ?> any, final String intAttrName, final IntMappingType intMappingType) { + + boolean result = false; + + Iterable<? extends ExternalResource> iterable = any instanceof User + ? userDAO.findAllResources((User) any) + : any instanceof Group + ? ((Group) any).getResources() + : Collections.<ExternalResource>emptySet(); + + for (Iterator<? extends ExternalResource> itor = iterable.iterator(); itor.hasNext() && !result;) { + ExternalResource resource = itor.next(); + if (resource.isEnforceMandatoryCondition()) { + result |= evaluateMandatoryCondition( + anyUtils, resource, any, intAttrName, intMappingType); + } + } + + return result; + } + + private SyncopeClientException checkMandatory(final AnyUtils anyUtils, final Any<?, ?, ?> any) { + SyncopeClientException reqValMissing = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing); + + // Check if there is some mandatory schema defined for which no value has been provided + List<PlainSchema> plainSchemas = plainSchemaDAO.findAll(); + for (PlainSchema schema : plainSchemas) { + if (any.getPlainAttr(schema.getKey()) == null + && !schema.isReadonly() + && (JexlUtils.evaluateMandatoryCondition(schema.getMandatoryCondition(), any) + || evaluateMandatoryCondition(anyUtils, any, schema.getKey(), + anyUtils.plainIntMappingType()))) { + + LOG.error("Mandatory schema " + schema.getKey() + " not provided with values"); + + reqValMissing.getElements().add(schema.getKey()); + } + } + + List<DerSchema> derSchemas = derSchemaDAO.findAll(); + for (DerSchema derSchema : derSchemas) { + if (any.getDerAttr(derSchema.getKey()) == null + && evaluateMandatoryCondition(anyUtils, any, derSchema.getKey(), + anyUtils.derIntMappingType())) { + + LOG.error("Mandatory derived schema " + derSchema.getKey() + " does not evaluate to any value"); + + reqValMissing.getElements().add(derSchema.getKey()); + } + } + + List<VirSchema> virSchemas = virSchemaDAO.findAll(); + for (VirSchema virSchema : virSchemas) { + if (any.getVirAttr(virSchema.getKey()) == null + && !virSchema.isReadonly() + && evaluateMandatoryCondition(anyUtils, any, virSchema.getKey(), + anyUtils.virIntMappingType())) { + + LOG.error("Mandatory virtual schema " + virSchema.getKey() + " not provided with values"); + + reqValMissing.getElements().add(virSchema.getKey()); + } + } + + return reqValMissing; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected PropagationByResource fill(final Any any, final AnyMod anyMod, final AnyUtils anyUtils, + final SyncopeClientCompositeException scce) { + + PropagationByResource propByRes = new PropagationByResource(); + + SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues); + + // 1. resources to be removed + for (String resourceToBeRemoved : anyMod.getResourcesToRemove()) { + ExternalResource resource = resourceDAO.find(resourceToBeRemoved); + if (resource != null) { + propByRes.add(ResourceOperation.DELETE, resource.getKey()); + ((Any<?, ?, ?>) any).remove(resource); + } + } + + LOG.debug("Resources to be removed:\n{}", propByRes); + + // 2. resources to be added + for (String resourceToBeAdded : anyMod.getResourcesToAdd()) { + ExternalResource resource = resourceDAO.find(resourceToBeAdded); + if (resource != null) { + propByRes.add(ResourceOperation.CREATE, resource.getKey()); + ((Any<?, ?, ?>) any).add(resource); + } + } + + LOG.debug("Resources to be added:\n{}", propByRes); + + Set<ExternalResource> externalResources = new HashSet<>(); + if (any instanceof User) { + externalResources.addAll(userDAO.findAllResources((User) any)); + } else if (any instanceof Group) { + externalResources.addAll(((Group) any).getResources()); + } else if (any instanceof AnyObject) { + externalResources.addAll(anyObjectDAO.findAllResources((AnyObject) any)); + } + + // 3. attributes to be removed + for (String attributeToBeRemoved : anyMod.getPlainAttrsToRemove()) { + PlainSchema schema = getPlainSchema(attributeToBeRemoved); + if (schema != null) { + PlainAttr<?> attr = any.getPlainAttr(schema.getKey()); + if (attr == null) { + LOG.debug("No attribute found for schema {}", schema); + } else { + String newValue = null; + for (AttrMod mod : anyMod.getPlainAttrsToUpdate()) { + if (schema.getKey().equals(mod.getSchema())) { + newValue = mod.getValuesToBeAdded().get(0); + } + } + + if (!schema.isUniqueConstraint() + || (!attr.getUniqueValue().getStringValue().equals(newValue))) { + + any.remove(attr); + plainAttrDAO.delete(attr.getKey(), anyUtils.plainAttrClass()); + } + } + + for (ExternalResource resource : externalResources) { + for (MappingItem mapItem : anyUtils.getMappingItems( + resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) { + + if (schema.getKey().equals(mapItem.getIntAttrName()) + && mapItem.getIntMappingType() == anyUtils.plainIntMappingType()) { + + propByRes.add(ResourceOperation.UPDATE, resource.getKey()); + + if (mapItem.isConnObjectKey() && attr != null && !attr.getValuesAsStrings().isEmpty()) { + propByRes.addOldAccountId(resource.getKey(), attr.getValuesAsStrings().get(0)); + } + } + } + } + } + } + + LOG.debug("Attributes to be removed:\n{}", propByRes); + + // 4. attributes to be updated + for (AttrMod attributeMod : anyMod.getPlainAttrsToUpdate()) { + PlainSchema schema = getPlainSchema(attributeMod.getSchema()); + PlainAttr attr = null; + if (schema != null) { + attr = any.getPlainAttr(schema.getKey()); + if (attr == null) { + attr = anyUtils.newPlainAttr(); + attr.setSchema(schema); + if (attr.getSchema() == null) { + LOG.debug("Ignoring {} because no valid schema or template was found", attributeMod); + } else { + attr.setOwner(any); + any.add(attr); + } + } + } + + if (schema != null && attr != null && attr.getSchema() != null) { + virtAttrHander.updateOnResourcesIfMappingMatches(any, anyUtils, schema.getKey(), + externalResources, anyUtils.plainIntMappingType(), propByRes); + + // 1.1 remove values + Set<Long> valuesToBeRemoved = new HashSet<>(); + for (String valueToBeRemoved : attributeMod.getValuesToBeRemoved()) { + if (attr.getSchema().isUniqueConstraint()) { + if (attr.getUniqueValue() != null + && valueToBeRemoved.equals(attr.getUniqueValue().getValueAsString())) { + + valuesToBeRemoved.add(attr.getUniqueValue().getKey()); + } + } else { + for (PlainAttrValue mav : ((PlainAttr<?>) attr).getValues()) { + if (valueToBeRemoved.equals(mav.getValueAsString())) { + valuesToBeRemoved.add(mav.getKey()); + } + } + } + } + for (Long attributeValueId : valuesToBeRemoved) { + plainAttrValueDAO.delete(attributeValueId, anyUtils.plainAttrValueClass()); + } + + // 1.2 add values + List<String> valuesToBeAdded = attributeMod.getValuesToBeAdded(); + if (valuesToBeAdded != null && !valuesToBeAdded.isEmpty() + && (!schema.isUniqueConstraint() || attr.getUniqueValue() == null + || !valuesToBeAdded.iterator().next().equals(attr.getUniqueValue().getValueAsString()))) { + + fillAttribute(attributeMod.getValuesToBeAdded(), anyUtils, schema, attr, invalidValues); + } + + // if no values are in, the attribute can be safely removed + if (attr.getValuesAsStrings().isEmpty()) { + plainAttrDAO.delete(attr); + } + } + } + + if (!invalidValues.isEmpty()) { + scce.addException(invalidValues); + } + + LOG.debug("Attributes to be updated:\n{}", propByRes); + + // 5. derived attributes to be removed + for (String derAttrToBeRemoved : anyMod.getDerAttrsToRemove()) { + DerSchema derSchema = getDerSchema(derAttrToBeRemoved); + if (derSchema != null) { + DerAttr derAttr = any.getDerAttr(derSchema.getKey()); + if (derAttr == null) { + LOG.debug("No derived attribute found for schema {}", derSchema.getKey()); + } else { + derAttrDAO.delete(derAttr); + } + + for (ExternalResource resource : externalResources) { + for (MappingItem mapItem : anyUtils.getMappingItems( + resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) { + + if (derSchema.getKey().equals(mapItem.getIntAttrName()) + && mapItem.getIntMappingType() == anyUtils.derIntMappingType()) { + + propByRes.add(ResourceOperation.UPDATE, resource.getKey()); + + if (mapItem.isConnObjectKey() && derAttr != null + && !derAttr.getValue(any.getPlainAttrs()).isEmpty()) { + + propByRes.addOldAccountId(resource.getKey(), + derAttr.getValue(any.getPlainAttrs())); + } + } + } + } + } + } + + LOG.debug("Derived attributes to be removed:\n{}", propByRes); + + // 6. derived attributes to be added + for (String derAttrToBeAdded : anyMod.getDerAttrsToAdd()) { + DerSchema derSchema = getDerSchema(derAttrToBeAdded); + if (derSchema != null) { + virtAttrHander.updateOnResourcesIfMappingMatches(any, anyUtils, derSchema.getKey(), + externalResources, anyUtils.derIntMappingType(), propByRes); + + DerAttr derAttr = anyUtils.newDerAttr(); + derAttr.setSchema(derSchema); + if (derAttr.getSchema() == null) { + LOG.debug("Ignoring {} because no valid schema or template was found", derAttrToBeAdded); + } else { + derAttr.setOwner(any); + any.add(derAttr); + } + } + } + + LOG.debug("Derived attributes to be added:\n{}", propByRes); + + // Finally, check if mandatory values are missing + SyncopeClientException requiredValuesMissing = checkMandatory(anyUtils, any); + if (!requiredValuesMissing.isEmpty()) { + scce.addException(requiredValuesMissing); + } + + // Throw composite exception if there is at least one element set in the composing exceptions + if (scce.hasExceptions()) { + throw scce; + } + + return propByRes; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected void fill(final Any any, final AnyTO anyTO, + final AnyUtils anyUtils, final SyncopeClientCompositeException scce) { + + // 1. attributes + SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues); + + // Only consider attributeTO with values + for (AttrTO attributeTO : anyTO.getPlainAttrs()) { + if (attributeTO.getValues() != null && !attributeTO.getValues().isEmpty()) { + PlainSchema schema = getPlainSchema(attributeTO.getSchema()); + + if (schema != null) { + PlainAttr attr = any.getPlainAttr(schema.getKey()); + if (attr == null) { + attr = anyUtils.newPlainAttr(); + attr.setSchema(schema); + } + if (attr.getSchema() == null) { + LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO); + } else { + fillAttribute(attributeTO.getValues(), anyUtils, schema, attr, invalidValues); + + if (!attr.getValuesAsStrings().isEmpty()) { + any.add(attr); + attr.setOwner(any); + } + } + } + } + } + + if (!invalidValues.isEmpty()) { + scce.addException(invalidValues); + } + + // 2. derived attributes + for (AttrTO attributeTO : anyTO.getDerAttrs()) { + DerSchema derSchema = getDerSchema(attributeTO.getSchema()); + + if (derSchema != null) { + DerAttr derAttr = anyUtils.newDerAttr(); + derAttr.setSchema(derSchema); + if (derAttr.getSchema() == null) { + LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO); + } else { + derAttr.setOwner(any); + any.add(derAttr); + } + } + } + + // 3. virtual attributes + for (AttrTO vattrTO : anyTO.getVirAttrs()) { + VirSchema virSchema = virtAttrHander.getVirSchema(vattrTO.getSchema()); + + if (virSchema != null) { + VirAttr virAttr = anyUtils.newVirAttr(); + virAttr.setSchema(virSchema); + if (virAttr.getSchema() == null) { + LOG.debug("Ignoring {} because no valid schema or template was found", vattrTO); + } else { + virAttr.setOwner(any); + any.add(virAttr); + } + } + } + + virtAttrHander.fillVirtual(any, anyTO.getVirAttrs(), anyUtils); + + // 4. realm & resources + Realm realm = realmDAO.find(anyTO.getRealm()); + if (realm == null) { + SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm); + noRealm.getElements().add( + "Invalid or null realm specified: " + anyTO.getRealm()); + scce.addException(noRealm); + } + ((Any<?, ?, ?>) any).setRealm(realm); + + for (String resourceName : anyTO.getResources()) { + ExternalResource resource = resourceDAO.find(resourceName); + + if (resource != null) { + ((Any<?, ?, ?>) any).add(resource); + } + } + + SyncopeClientException requiredValuesMissing = checkMandatory(anyUtils, any); + if (!requiredValuesMissing.isEmpty()) { + scce.addException(requiredValuesMissing); + } + + // Throw composite exception if there is at least one element set in the composing exceptions + if (scce.hasExceptions()) { + throw scce; + } + } + + protected void fillTO(final AnyTO anyTO, + final String realmFullPath, + final Collection<? extends PlainAttr<?>> attrs, + final Collection<? extends DerAttr<?>> derAttrs, + final Collection<? extends VirAttr<?>> virAttrs, + final Collection<? extends ExternalResource> resources) { + + AttrTO attributeTO; + for (PlainAttr<?> attr : attrs) { + attributeTO = new AttrTO(); + attributeTO.setSchema(attr.getSchema().getKey()); + attributeTO.getValues().addAll(attr.getValuesAsStrings()); + attributeTO.setReadonly(attr.getSchema().isReadonly()); + + anyTO.getPlainAttrs().add(attributeTO); + } + + for (DerAttr<?> derAttr : derAttrs) { + attributeTO = new AttrTO(); + attributeTO.setSchema(derAttr.getSchema().getKey()); + attributeTO.getValues().add(derAttr.getValue(attrs)); + attributeTO.setReadonly(true); + + anyTO.getDerAttrs().add(attributeTO); + } + + for (VirAttr<?> virAttr : virAttrs) { + attributeTO = new AttrTO(); + attributeTO.setSchema(virAttr.getSchema().getKey()); + attributeTO.getValues().addAll(virAttr.getValues()); + attributeTO.setReadonly(virAttr.getSchema().isReadonly()); + + anyTO.getVirAttrs().add(attributeTO); + } + + anyTO.setRealm(realmFullPath); + for (ExternalResource resource : resources) { + anyTO.getResources().add(resource.getKey()); + } + } + + protected Map<String, String> getConnObjectKeys(final Any<?, ?, ?> any) { + Map<String, String> connObjectKeys = new HashMap<>(); + + Iterable<? extends ExternalResource> iterable = any instanceof User + ? userDAO.findAllResources((User) any) + : any instanceof AnyObject + ? anyObjectDAO.findAllResources((AnyObject) any) + : ((Group) any).getResources(); + for (ExternalResource resource : iterable) { + Provision provision = resource.getProvision(any.getType()); + if (provision.getMapping() != null) { + MappingItem connObjectKeyItem = anyUtilsFactory.getInstance(any).getConnObjectKeyItem(provision); + if (connObjectKeyItem == null) { + throw new NotFoundException( + "ConnObjectKey mapping for " + any.getType().getKey() + " " + any.getKey() + + " on resource '" + resource.getKey() + "'"); + } + + connObjectKeys.put(resource.getKey(), MappingUtils.getConnObjectKeyValue(any, provision)); + } + } + + return connObjectKeys; + } +}
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java deleted file mode 100644 index b94ffa2..0000000 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java +++ /dev/null @@ -1,805 +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.provisioning.java.data; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.apache.commons.lang3.StringUtils; -import org.apache.syncope.common.lib.SyncopeClientCompositeException; -import org.apache.syncope.common.lib.SyncopeClientException; -import org.apache.syncope.common.lib.mod.AbstractAttributableMod; -import org.apache.syncope.common.lib.mod.AbstractSubjectMod; -import org.apache.syncope.common.lib.mod.AttrMod; -import org.apache.syncope.common.lib.to.AbstractAttributableTO; -import org.apache.syncope.common.lib.to.AbstractSubjectTO; -import org.apache.syncope.common.lib.to.AttrTO; -import org.apache.syncope.common.lib.types.AttributableType; -import org.apache.syncope.common.lib.types.ClientExceptionType; -import org.apache.syncope.common.lib.types.IntMappingType; -import org.apache.syncope.common.lib.types.MappingPurpose; -import org.apache.syncope.common.lib.types.ResourceOperation; -import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException; -import org.apache.syncope.core.persistence.api.dao.DerAttrDAO; -import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; -import org.apache.syncope.core.persistence.api.dao.MembershipDAO; -import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO; -import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.PolicyDAO; -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.VirSchemaDAO; -import org.apache.syncope.core.persistence.api.entity.Attributable; -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.DerAttr; -import org.apache.syncope.core.persistence.api.entity.DerSchema; -import org.apache.syncope.core.persistence.api.entity.EntityFactory; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.MappingItem; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -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.Schema; -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.VirSchema; -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.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.GVirAttrTemplate; -import org.apache.syncope.core.persistence.api.entity.group.Group; -import org.apache.syncope.core.persistence.api.entity.user.UDerAttr; -import org.apache.syncope.core.persistence.api.entity.user.UDerSchema; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema; -import org.apache.syncope.common.lib.types.PropagationByResource; -import org.apache.syncope.core.provisioning.java.VirAttrHandler; -import org.apache.syncope.core.misc.MappingUtils; -import org.apache.syncope.core.misc.jexl.JexlUtils; -import org.apache.syncope.core.persistence.api.dao.NotFoundException; -import org.apache.syncope.core.persistence.api.dao.RealmDAO; -import org.apache.syncope.core.persistence.api.entity.Realm; -import org.apache.syncope.core.persistence.api.entity.user.User; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -abstract class AbstractAttributableDataBinder { - - /** - * Logger. - */ - protected static final Logger LOG = LoggerFactory.getLogger(AbstractAttributableDataBinder.class); - - @Autowired - protected RealmDAO realmDAO; - - @Autowired - protected GroupDAO groupDAO; - - @Autowired - protected PlainSchemaDAO plainSchemaDAO; - - @Autowired - protected DerSchemaDAO derSchemaDAO; - - @Autowired - protected VirSchemaDAO virSchemaDAO; - - @Autowired - protected PlainAttrDAO plainAttrDAO; - - @Autowired - protected DerAttrDAO derAttrDAO; - - @Autowired - protected VirAttrDAO virAttrDAO; - - @Autowired - protected PlainAttrValueDAO plainAttrValueDAO; - - @Autowired - protected UserDAO userDAO; - - @Autowired - protected ExternalResourceDAO resourceDAO; - - @Autowired - protected MembershipDAO membershipDAO; - - @Autowired - protected PolicyDAO policyDAO; - - @Autowired - protected EntityFactory entityFactory; - - @Autowired - protected AttributableUtilsFactory attrUtilsFactory; - - @Autowired - protected VirAttrHandler virtAttrHander; - - protected void setRealm(final Subject<?, ?, ?> subject, final AbstractSubjectMod subjectMod) { - if (StringUtils.isNotBlank(subjectMod.getRealm())) { - Realm newRealm = realmDAO.find(subjectMod.getRealm()); - if (newRealm == null) { - LOG.warn("Invalid realm specified: {}, ignoring", subjectMod.getRealm()); - } else { - subject.setRealm(newRealm); - } - } - } - - @SuppressWarnings("unchecked") - protected <T extends Schema> T getSchema(final String schemaName, final Class<T> reference) { - T result = null; - - if (PlainSchema.class.isAssignableFrom(reference)) { - result = (T) getPlainSchema(schemaName, (Class<? extends PlainSchema>) reference); - } else if (DerSchema.class.isAssignableFrom(reference)) { - result = (T) getDerSchema(schemaName, (Class<? extends DerSchema>) reference); - } else if (VirSchema.class.isAssignableFrom(reference)) { - result = (T) virtAttrHander.getVirSchema(schemaName, (Class<? extends VirSchema>) reference); - } - - return result; - } - - protected <T extends PlainSchema> T getPlainSchema(final String schemaName, final Class<T> reference) { - T schema = null; - if (StringUtils.isNotBlank(schemaName)) { - schema = plainSchemaDAO.find(schemaName, reference); - - // safely ignore invalid schemas from AttrTO - if (schema == null) { - LOG.debug("Ignoring invalid schema {}", schemaName); - } else if (schema.isReadonly()) { - schema = null; - - LOG.debug("Ignoring readonly schema {}", schemaName); - } - } - - return schema; - } - - private <T extends DerSchema> T getDerSchema(final String derSchemaName, final Class<T> reference) { - T derivedSchema = null; - if (StringUtils.isNotBlank(derSchemaName)) { - derivedSchema = derSchemaDAO.find(derSchemaName, reference); - if (derivedSchema == null) { - LOG.debug("Ignoring invalid derived schema {}", derSchemaName); - } - } - - return derivedSchema; - } - - protected void fillAttribute(final List<String> values, final AttributableUtils attributableUtil, - final PlainSchema schema, final PlainAttr attr, final SyncopeClientException invalidValues) { - - // if schema is multivalue, all values are considered for addition; - // otherwise only the fist one - if provided - is considered - List<String> valuesProvided = schema.isMultivalue() - ? values - : (values.isEmpty() - ? Collections.<String>emptyList() - : Collections.singletonList(values.iterator().next())); - - for (String value : valuesProvided) { - if (value == null || value.isEmpty()) { - LOG.debug("Null value for {}, ignoring", schema.getKey()); - } else { - try { - attr.addValue(value, attributableUtil); - } catch (InvalidPlainAttrValueException e) { - LOG.warn("Invalid value for attribute " + schema.getKey() + ": " + value, e); - - invalidValues.getElements().add(schema.getKey() + ": " + value + " - " + e.getMessage()); - } - } - } - } - - private boolean evaluateMandatoryCondition(final AttributableUtils attrUtils, final ExternalResource resource, - final Attributable<?, ?, ?> attributable, final String intAttrName, final IntMappingType intMappingType) { - - boolean result = false; - - Collection<MappingItem> mappings = MappingUtils.getMatchingMappingItems( - attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION), intAttrName, intMappingType); - for (Iterator<MappingItem> itor = mappings.iterator(); itor.hasNext() && !result;) { - MappingItem mapping = itor.next(); - result |= JexlUtils.evaluateMandatoryCondition(mapping.getMandatoryCondition(), attributable); - } - - return result; - } - - private boolean evaluateMandatoryCondition(final AttributableUtils attrUtils, - final Attributable<?, ?, ?> attributable, final String intAttrName, final IntMappingType intMappingType) { - - boolean result = false; - - Iterable<? extends ExternalResource> iterable = attributable instanceof User - ? userDAO.findAllResources((User) attributable) - : attributable instanceof Group - ? ((Group) attributable).getResources() - : Collections.<ExternalResource>emptySet(); - - for (Iterator<? extends ExternalResource> itor = iterable.iterator(); itor.hasNext() && !result;) { - ExternalResource resource = itor.next(); - if (resource.isEnforceMandatoryCondition()) { - result |= evaluateMandatoryCondition( - attrUtils, resource, attributable, intAttrName, intMappingType); - } - } - - return result; - } - - private SyncopeClientException checkMandatory(final AttributableUtils attrUtils, - final Attributable<?, ?, ?> attributable) { - - SyncopeClientException reqValMissing = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing); - - // Check if there is some mandatory schema defined for which no value has been provided - List<? extends PlainSchema> plainSchemas; - switch (attrUtils.getType()) { - case GROUP: - plainSchemas = ((Group) attributable).getAttrTemplateSchemas(GPlainAttrTemplate.class); - break; - - case MEMBERSHIP: - plainSchemas = ((Membership) attributable).getGroup().getAttrTemplateSchemas(MPlainAttrTemplate.class); - break; - - case USER: - default: - plainSchemas = plainSchemaDAO.findAll(attrUtils.plainSchemaClass()); - } - for (PlainSchema schema : plainSchemas) { - if (attributable.getPlainAttr(schema.getKey()) == null - && !schema.isReadonly() - && (JexlUtils.evaluateMandatoryCondition(schema.getMandatoryCondition(), attributable) - || evaluateMandatoryCondition(attrUtils, attributable, schema.getKey(), - attrUtils.plainIntMappingType()))) { - - LOG.error("Mandatory schema " + schema.getKey() + " not provided with values"); - - reqValMissing.getElements().add(schema.getKey()); - } - } - - List<? extends DerSchema> derSchemas; - switch (attrUtils.getType()) { - case GROUP: - derSchemas = ((Group) attributable).getAttrTemplateSchemas(GDerAttrTemplate.class); - break; - - case MEMBERSHIP: - derSchemas = ((Membership) attributable).getGroup().getAttrTemplateSchemas(MDerAttrTemplate.class); - break; - - case USER: - default: - derSchemas = derSchemaDAO.findAll(attrUtils.derSchemaClass()); - } - for (DerSchema derSchema : derSchemas) { - if (attributable.getDerAttr(derSchema.getKey()) == null - && evaluateMandatoryCondition(attrUtils, attributable, derSchema.getKey(), - attrUtils.derIntMappingType())) { - - LOG.error("Mandatory derived schema " + derSchema.getKey() + " does not evaluate to any value"); - - reqValMissing.getElements().add(derSchema.getKey()); - } - } - - List<? extends VirSchema> virSchemas; - switch (attrUtils.getType()) { - case GROUP: - virSchemas = ((Group) attributable).getAttrTemplateSchemas(GVirAttrTemplate.class); - break; - - case MEMBERSHIP: - virSchemas = ((Membership) attributable).getGroup().getAttrTemplateSchemas(MVirAttrTemplate.class); - break; - - case USER: - default: - virSchemas = virSchemaDAO.findAll(attrUtils.virSchemaClass()); - } - for (VirSchema virSchema : virSchemas) { - if (attributable.getVirAttr(virSchema.getKey()) == null - && !virSchema.isReadonly() - && evaluateMandatoryCondition(attrUtils, attributable, virSchema.getKey(), - attrUtils.virIntMappingType())) { - - LOG.error("Mandatory virtual schema " + virSchema.getKey() + " not provided with values"); - - reqValMissing.getElements().add(virSchema.getKey()); - } - } - - return reqValMissing; - } - - private void setPlainAttrSchema(final Attributable<?, ?, ?> attributable, - final PlainAttr attr, final PlainSchema schema) { - - if (attr instanceof UPlainAttr) { - ((UPlainAttr) attr).setSchema((UPlainSchema) schema); - } else if (attr instanceof GPlainAttr) { - GPlainAttrTemplate template = - ((Group) attributable).getAttrTemplate(GPlainAttrTemplate.class, schema.getKey()); - if (template != null) { - ((GPlainAttr) attr).setTemplate(template); - } - } else if (attr instanceof MPlainAttr) { - MPlainAttrTemplate template = ((Membership) attributable).getGroup(). - getAttrTemplate(MPlainAttrTemplate.class, schema.getKey()); - if (template != null) { - ((MPlainAttr) attr).setTemplate(template); - } - } - } - - private void setDerAttrSchema(final Attributable<?, ?, ?> attributable, - final DerAttr derAttr, final DerSchema derSchema) { - - if (derAttr instanceof UDerAttr) { - ((UDerAttr) derAttr).setSchema((UDerSchema) derSchema); - } else if (derAttr instanceof GDerAttr) { - GDerAttrTemplate template = ((Group) attributable). - getAttrTemplate(GDerAttrTemplate.class, derSchema.getKey()); - if (template != null) { - ((GDerAttr) derAttr).setTemplate(template); - } - } else if (derAttr instanceof MDerAttr) { - MDerAttrTemplate template = ((Membership) attributable).getGroup(). - getAttrTemplate(MDerAttrTemplate.class, derSchema.getKey()); - if (template != null) { - ((MDerAttr) derAttr).setTemplate(template); - } - } - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected PropagationByResource fill(final Attributable attributable, - final AbstractAttributableMod attributableMod, final AttributableUtils attrUtils, - final SyncopeClientCompositeException scce) { - - PropagationByResource propByRes = new PropagationByResource(); - - SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues); - - if (attributable instanceof Subject && attributableMod instanceof AbstractSubjectMod) { - // 1. resources to be removed - for (String resourceToBeRemoved : ((AbstractSubjectMod) attributableMod).getResourcesToRemove()) { - ExternalResource resource = resourceDAO.find(resourceToBeRemoved); - if (resource != null) { - propByRes.add(ResourceOperation.DELETE, resource.getKey()); - ((Subject<?, ?, ?>) attributable).removeResource(resource); - } - } - - LOG.debug("Resources to be removed:\n{}", propByRes); - - // 2. resources to be added - for (String resourceToBeAdded : ((AbstractSubjectMod) attributableMod).getResourcesToAdd()) { - ExternalResource resource = resourceDAO.find(resourceToBeAdded); - if (resource != null) { - propByRes.add(ResourceOperation.CREATE, resource.getKey()); - ((Subject<?, ?, ?>) attributable).addResource(resource); - } - } - - LOG.debug("Resources to be added:\n{}", propByRes); - } - - Set<ExternalResource> externalResources = new HashSet<>(); - if (attributable instanceof User) { - externalResources.addAll(userDAO.findAllResources((User) attributable)); - } else if (attributable instanceof Group) { - externalResources.addAll(((Group) attributable).getResources()); - } else if (attributable instanceof Membership) { - externalResources.addAll(userDAO.findAllResources(((Membership) attributable).getUser())); - externalResources.addAll(((Membership) attributable).getGroup().getResources()); - } - - // 3. attributes to be removed - for (String attributeToBeRemoved : attributableMod.getPlainAttrsToRemove()) { - PlainSchema schema = getPlainSchema(attributeToBeRemoved, attrUtils.plainSchemaClass()); - if (schema != null) { - PlainAttr attr = attributable.getPlainAttr(schema.getKey()); - if (attr == null) { - LOG.debug("No attribute found for schema {}", schema); - } else { - String newValue = null; - for (AttrMod mod : attributableMod.getPlainAttrsToUpdate()) { - if (schema.getKey().equals(mod.getSchema())) { - newValue = mod.getValuesToBeAdded().get(0); - } - } - - if (!schema.isUniqueConstraint() - || (!attr.getUniqueValue().getStringValue().equals(newValue))) { - - attributable.removePlainAttr(attr); - plainAttrDAO.delete(attr.getKey(), attrUtils.plainAttrClass()); - } - } - - if (attributable instanceof Subject) { - for (ExternalResource resource : externalResources) { - for (MappingItem mapItem : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) { - if (schema.getKey().equals(mapItem.getIntAttrName()) - && mapItem.getIntMappingType() == attrUtils.plainIntMappingType()) { - - propByRes.add(ResourceOperation.UPDATE, resource.getKey()); - - if (mapItem.isAccountid() && attr != null && !attr.getValuesAsStrings().isEmpty()) { - propByRes.addOldAccountId(resource.getKey(), attr.getValuesAsStrings().get(0)); - } - } - } - } - } - } - } - - LOG.debug("Attributes to be removed:\n{}", propByRes); - - // 4. attributes to be updated - for (AttrMod attributeMod : attributableMod.getPlainAttrsToUpdate()) { - PlainSchema schema = getPlainSchema(attributeMod.getSchema(), attrUtils.plainSchemaClass()); - PlainAttr attr = null; - if (schema != null) { - attr = attributable.getPlainAttr(schema.getKey()); - if (attr == null) { - attr = attrUtils.newPlainAttr(); - setPlainAttrSchema(attributable, attr, schema); - if (attr.getSchema() == null) { - LOG.debug("Ignoring {} because no valid schema or template was found", attributeMod); - } else { - attr.setOwner(attributable); - attributable.addPlainAttr(attr); - } - } - } - - if (schema != null && attr != null && attr.getSchema() != null) { - if (attributable instanceof Subject) { - virtAttrHander.updateOnResourcesIfMappingMatches(attrUtils, schema.getKey(), - externalResources, attrUtils.plainIntMappingType(), propByRes); - } else if (attributable instanceof Membership) { - virtAttrHander.updateOnResourcesIfMappingMatches(attrUtils, schema.getKey(), - externalResources, IntMappingType.MembershipPlainSchema, propByRes); - } - - // 1.1 remove values - Set<Long> valuesToBeRemoved = new HashSet<>(); - for (String valueToBeRemoved : attributeMod.getValuesToBeRemoved()) { - if (attr.getSchema().isUniqueConstraint()) { - if (attr.getUniqueValue() != null - && valueToBeRemoved.equals(attr.getUniqueValue().getValueAsString())) { - - valuesToBeRemoved.add(attr.getUniqueValue().getKey()); - } - } else { - for (PlainAttrValue mav : attr.getValues()) { - if (valueToBeRemoved.equals(mav.getValueAsString())) { - valuesToBeRemoved.add(mav.getKey()); - } - } - } - } - for (Long attributeValueId : valuesToBeRemoved) { - plainAttrValueDAO.delete(attributeValueId, attrUtils.plainAttrValueClass()); - } - - // 1.2 add values - List<String> valuesToBeAdded = attributeMod.getValuesToBeAdded(); - if (valuesToBeAdded != null && !valuesToBeAdded.isEmpty() - && (!schema.isUniqueConstraint() || attr.getUniqueValue() == null - || !valuesToBeAdded.iterator().next().equals(attr.getUniqueValue().getValueAsString()))) { - - fillAttribute(attributeMod.getValuesToBeAdded(), attrUtils, schema, attr, invalidValues); - } - - // if no values are in, the attribute can be safely removed - if (attr.getValuesAsStrings().isEmpty()) { - plainAttrDAO.delete(attr); - } - } - } - - if (!invalidValues.isEmpty()) { - scce.addException(invalidValues); - } - - LOG.debug("Attributes to be updated:\n{}", propByRes); - - // 5. derived attributes to be removed - for (String derAttrToBeRemoved : attributableMod.getDerAttrsToRemove()) { - DerSchema derSchema = getDerSchema(derAttrToBeRemoved, attrUtils.derSchemaClass()); - if (derSchema != null) { - DerAttr derAttr = attributable.getDerAttr(derSchema.getKey()); - if (derAttr == null) { - LOG.debug("No derived attribute found for schema {}", derSchema.getKey()); - } else { - derAttrDAO.delete(derAttr); - } - - if (attributable instanceof Subject) { - for (ExternalResource resource : externalResources) { - for (MappingItem mapItem : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) { - if (derSchema.getKey().equals(mapItem.getIntAttrName()) - && mapItem.getIntMappingType() == attrUtils.derIntMappingType()) { - - propByRes.add(ResourceOperation.UPDATE, resource.getKey()); - - if (mapItem.isAccountid() && derAttr != null - && !derAttr.getValue(attributable.getPlainAttrs()).isEmpty()) { - - propByRes.addOldAccountId(resource.getKey(), - derAttr.getValue(attributable.getPlainAttrs())); - } - } - } - } - } - } - } - - LOG.debug("Derived attributes to be removed:\n{}", propByRes); - - // 6. derived attributes to be added - for (String derAttrToBeAdded : attributableMod.getDerAttrsToAdd()) { - DerSchema derSchema = getDerSchema(derAttrToBeAdded, attrUtils.derSchemaClass()); - if (derSchema != null) { - if (attributable instanceof Subject) { - virtAttrHander.updateOnResourcesIfMappingMatches(attrUtils, derSchema.getKey(), - externalResources, attrUtils.derIntMappingType(), propByRes); - } else if (attributable instanceof Membership) { - virtAttrHander.updateOnResourcesIfMappingMatches(attrUtils, derSchema.getKey(), - externalResources, IntMappingType.MembershipDerivedSchema, propByRes); - } - - DerAttr derAttr = attrUtils.newDerAttr(); - setDerAttrSchema(attributable, derAttr, derSchema); - if (derAttr.getSchema() == null) { - LOG.debug("Ignoring {} because no valid schema or template was found", derAttrToBeAdded); - } else { - derAttr.setOwner(attributable); - attributable.addDerAttr(derAttr); - } - } - } - - LOG.debug("Derived attributes to be added:\n{}", propByRes); - - // 7. virtual attributes: for users and groups this is delegated to PropagationManager - if (AttributableType.USER != attrUtils.getType() && AttributableType.GROUP != attrUtils.getType()) { - virtAttrHander.fillVirtual(attributable, attributableMod.getVirAttrsToRemove(), - attributableMod.getVirAttrsToUpdate(), attrUtils); - } - - // Finally, check if mandatory values are missing - SyncopeClientException requiredValuesMissing = checkMandatory(attrUtils, attributable); - if (!requiredValuesMissing.isEmpty()) { - scce.addException(requiredValuesMissing); - } - - // Throw composite exception if there is at least one element set in the composing exceptions - if (scce.hasExceptions()) { - throw scce; - } - - return propByRes; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected void fill(final Attributable attributable, final AbstractAttributableTO attributableTO, - final AttributableUtils attrUtils, final SyncopeClientCompositeException scce) { - - // 1. attributes - SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues); - - // Only consider attributeTO with values - for (AttrTO attributeTO : attributableTO.getPlainAttrs()) { - if (attributeTO.getValues() != null && !attributeTO.getValues().isEmpty()) { - PlainSchema schema = getPlainSchema(attributeTO.getSchema(), attrUtils.plainSchemaClass()); - - if (schema != null) { - PlainAttr attr = attributable.getPlainAttr(schema.getKey()); - if (attr == null) { - attr = attrUtils.newPlainAttr(); - setPlainAttrSchema(attributable, attr, schema); - } - if (attr.getSchema() == null) { - LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO); - } else { - fillAttribute(attributeTO.getValues(), attrUtils, schema, attr, invalidValues); - - if (!attr.getValuesAsStrings().isEmpty()) { - attributable.addPlainAttr(attr); - attr.setOwner(attributable); - } - } - } - } - } - - if (!invalidValues.isEmpty()) { - scce.addException(invalidValues); - } - - // 2. derived attributes - for (AttrTO attributeTO : attributableTO.getDerAttrs()) { - DerSchema derSchema = getDerSchema(attributeTO.getSchema(), attrUtils.derSchemaClass()); - - if (derSchema != null) { - DerAttr derAttr = attrUtils.newDerAttr(); - setDerAttrSchema(attributable, derAttr, derSchema); - if (derAttr.getSchema() == null) { - LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO); - } else { - derAttr.setOwner(attributable); - attributable.addDerAttr(derAttr); - } - } - } - - // 3. user and group virtual attributes will be evaluated by the propagation manager only (if needed). - if (AttributableType.USER == attrUtils.getType() || AttributableType.GROUP == attrUtils.getType()) { - for (AttrTO vattrTO : attributableTO.getVirAttrs()) { - VirSchema virSchema = virtAttrHander.getVirSchema(vattrTO.getSchema(), attrUtils.virSchemaClass()); - - if (virSchema != null) { - VirAttr virAttr = attrUtils.newVirAttr(); - virtAttrHander.setVirAttrSchema(attributable, virAttr, virSchema); - if (virAttr.getSchema() == null) { - LOG.debug("Ignoring {} because no valid schema or template was found", vattrTO); - } else { - virAttr.setOwner(attributable); - attributable.addVirAttr(virAttr); - } - } - } - } - - virtAttrHander.fillVirtual(attributable, attributableTO.getVirAttrs(), attrUtils); - - // 4. realm & resources - if (attributable instanceof Subject && attributableTO instanceof AbstractSubjectTO) { - Realm realm = realmDAO.find(((AbstractSubjectTO) attributableTO).getRealm()); - if (realm == null) { - SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm); - noRealm.getElements().add( - "Invalid or null realm specified: " + ((AbstractSubjectTO) attributableTO).getRealm()); - scce.addException(noRealm); - } - ((Subject<?, ?, ?>) attributable).setRealm(realm); - - for (String resourceName : ((AbstractSubjectTO) attributableTO).getResources()) { - ExternalResource resource = resourceDAO.find(resourceName); - - if (resource != null) { - ((Subject<?, ?, ?>) attributable).addResource(resource); - } - } - } - - SyncopeClientException requiredValuesMissing = checkMandatory(attrUtils, attributable); - if (!requiredValuesMissing.isEmpty()) { - scce.addException(requiredValuesMissing); - } - - // Throw composite exception if there is at least one element set in the composing exceptions - if (scce.hasExceptions()) { - throw scce; - } - } - - protected void fillTO(final AbstractAttributableTO attributableTO, - final String realmFullPath, - final Collection<? extends PlainAttr> attrs, - final Collection<? extends DerAttr> derAttrs, - final Collection<? extends VirAttr> virAttrs, - final Collection<? extends ExternalResource> resources) { - - AttrTO attributeTO; - for (PlainAttr attr : attrs) { - attributeTO = new AttrTO(); - attributeTO.setSchema(attr.getSchema().getKey()); - attributeTO.getValues().addAll(attr.getValuesAsStrings()); - attributeTO.setReadonly(attr.getSchema().isReadonly()); - - attributableTO.getPlainAttrs().add(attributeTO); - } - - for (DerAttr derAttr : derAttrs) { - attributeTO = new AttrTO(); - attributeTO.setSchema(derAttr.getSchema().getKey()); - attributeTO.getValues().add(derAttr.getValue(attrs)); - attributeTO.setReadonly(true); - - attributableTO.getDerAttrs().add(attributeTO); - } - - for (VirAttr virAttr : virAttrs) { - attributeTO = new AttrTO(); - attributeTO.setSchema(virAttr.getSchema().getKey()); - attributeTO.getValues().addAll(virAttr.getValues()); - attributeTO.setReadonly(virAttr.getSchema().isReadonly()); - - attributableTO.getVirAttrs().add(attributeTO); - } - - if (attributableTO instanceof AbstractSubjectTO) { - AbstractSubjectTO subjectTO = AbstractSubjectTO.class.cast(attributableTO); - subjectTO.setRealm(realmFullPath); - for (ExternalResource resource : resources) { - subjectTO.getResources().add(resource.getKey()); - } - } - } - - protected Map<String, String> getAccountIds(final Subject<?, ?, ?> subject, final AttributableType type) { - Map<String, String> accountIds = new HashMap<>(); - - Iterable<? extends ExternalResource> iterable = subject instanceof User - ? userDAO.findAllResources((User) subject) - : ((Group) subject).getResources(); - for (ExternalResource resource : iterable) { - if ((type == AttributableType.USER && resource.getUmapping() != null) - || (type == AttributableType.GROUP && resource.getGmapping() != null)) { - - MappingItem accountIdItem = attrUtilsFactory.getInstance(type).getAccountIdItem(resource); - if (accountIdItem == null) { - throw new NotFoundException( - "AccountId mapping for " + type + " " + subject.getKey() - + " on resource '" + resource.getKey() + "'"); - } - - accountIds.put(resource.getKey(), MappingUtils.getAccountIdValue(subject, resource, accountIdItem)); - } - } - - return accountIds; - } -} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java index 5e2dc1b..fe5668d 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java @@ -18,26 +18,33 @@ */ package org.apache.syncope.core.provisioning.java.data; +import static org.apache.syncope.core.provisioning.java.data.AbstractAnyDataBinder.LOG; + import org.apache.syncope.core.provisioning.api.data.ConfigurationDataBinder; import java.util.Collections; +import java.util.List; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.AttrTO; import org.apache.syncope.common.lib.to.ConfTO; -import org.apache.syncope.common.lib.types.AttributableType; import org.apache.syncope.common.lib.types.ClientExceptionType; +import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException; import org.apache.syncope.core.persistence.api.dao.NotFoundException; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; +import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; +import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr; -import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema; +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.conf.Conf; +import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; import org.springframework.stereotype.Component; @Component -public class ConfigurationDataBinderImpl extends AbstractAttributableDataBinder implements ConfigurationDataBinder { +public class ConfigurationDataBinderImpl extends AbstractAnyDataBinder implements ConfigurationDataBinder { @Override public ConfTO getConfTO(final Conf conf) { - final ConfTO confTO = new ConfTO(); + ConfTO confTO = new ConfTO(); confTO.setKey(conf.getKey()); fillTO(confTO, null, conf.getPlainAttrs(), @@ -48,7 +55,7 @@ public class ConfigurationDataBinderImpl extends AbstractAttributableDataBinder @Override public AttrTO getAttrTO(final CPlainAttr attr) { - final AttrTO attributeTO = new AttrTO(); + AttrTO attributeTO = new AttrTO(); attributeTO.setSchema(attr.getSchema().getKey()); attributeTO.getValues().addAll(attr.getValuesAsStrings()); attributeTO.setReadonly(attr.getSchema().isReadonly()); @@ -56,9 +63,43 @@ public class ConfigurationDataBinderImpl extends AbstractAttributableDataBinder return attributeTO; } + private void fillAttribute(final List<String> values, + final PlainSchema schema, final CPlainAttr attr, final SyncopeClientException invalidValues) { + + // if schema is multivalue, all values are considered for addition; + // otherwise only the fist one - if provided - is considered + List<String> valuesProvided = schema.isMultivalue() + ? values + : (values.isEmpty() + ? Collections.<String>emptyList() + : Collections.singletonList(values.iterator().next())); + + for (String value : valuesProvided) { + if (value == null || value.isEmpty()) { + LOG.debug("Null value for {}, ignoring", schema.getKey()); + } else { + try { + PlainAttrValue attrValue; + if (schema.isUniqueConstraint()) { + attrValue = entityFactory.newEntity(CPlainAttrUniqueValue.class); + ((PlainAttrUniqueValue) attrValue).setSchema(schema); + } else { + attrValue = entityFactory.newEntity(CPlainAttrValue.class); + } + + attr.add(value, attrValue); + } catch (InvalidPlainAttrValueException e) { + LOG.warn("Invalid value for attribute " + schema.getKey() + ": " + value, e); + + invalidValues.getElements().add(schema.getKey() + ": " + value + " - " + e.getMessage()); + } + } + } + } + @Override public CPlainAttr getAttribute(final AttrTO attributeTO) { - CPlainSchema schema = getPlainSchema(attributeTO.getSchema(), CPlainSchema.class); + PlainSchema schema = getPlainSchema(attributeTO.getSchema()); if (schema == null) { throw new NotFoundException("Conf schema " + attributeTO.getSchema()); } else { @@ -66,8 +107,7 @@ public class ConfigurationDataBinderImpl extends AbstractAttributableDataBinder CPlainAttr attr = entityFactory.newEntity(CPlainAttr.class); attr.setSchema(schema); - fillAttribute(attributeTO.getValues(), attrUtilsFactory.getInstance(AttributableType.CONFIGURATION), - schema, attr, invalidValues); + fillAttribute(attributeTO.getValues(), schema, attr, invalidValues); if (!invalidValues.isEmpty()) { throw invalidValues; http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java index efe7771..17370e6 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java @@ -18,30 +18,14 @@ */ package org.apache.syncope.core.provisioning.java.data; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import org.apache.syncope.common.lib.SyncopeClientCompositeException; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.mod.GroupMod; import org.apache.syncope.common.lib.to.GroupTO; -import org.apache.syncope.common.lib.types.AttributableType; +import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.ResourceOperation; -import org.apache.syncope.core.persistence.api.entity.AttrTemplate; -import org.apache.syncope.core.persistence.api.entity.Schema; -import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate; -import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema; -import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate; -import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema; -import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate; -import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema; -import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate; -import org.apache.syncope.core.persistence.api.entity.group.GDerSchema; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate; -import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema; -import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate; -import org.apache.syncope.core.persistence.api.entity.group.GVirSchema; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.common.lib.types.PropagationByResource; @@ -50,47 +34,20 @@ import org.apache.syncope.core.misc.ConnObjectUtils; import org.apache.syncope.core.misc.search.SearchCondConverter; import org.apache.syncope.core.persistence.api.dao.search.SearchCond; import org.apache.syncope.core.persistence.api.entity.DynGroupMembership; +import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership; +import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @Component @Transactional(rollbackFor = { Throwable.class }) -public class GroupDataBinderImpl extends AbstractAttributableDataBinder implements GroupDataBinder { +public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupDataBinder { @Autowired private ConnObjectUtils connObjectUtils; - private <T extends AttrTemplate<S>, S extends Schema> void setAttrTemplates( - final Group group, final List<String> schemaNames, - final Class<T> templateClass, final Class<S> schemaClass) { - - List<T> toRemove = new ArrayList<>(); - for (T template : group.getAttrTemplates(templateClass)) { - if (!schemaNames.contains(template.getSchema().getKey())) { - toRemove.add(template); - } - } - group.getAttrTemplates(templateClass).removeAll(toRemove); - - for (String schemaName : schemaNames) { - if (group.getAttrTemplate(templateClass, schemaName) == null) { - S schema = getSchema(schemaName, schemaClass); - if (schema != null) { - try { - T template = entityFactory.newEntity(templateClass); - template.setSchema(schema); - template.setOwner(group); - group.getAttrTemplates(templateClass).add(template); - } catch (Exception e) { - LOG.error("Could not create template for {}", templateClass, e); - } - } - } - } - } - - private void setDynMembership(final Group group, final String dynMembershipFIQL) { + private void setDynMembership(final Group group, final AnyTypeKind anyTypeKind, final String dynMembershipFIQL) { SearchCond dynMembershipCond = SearchCondConverter.convert(dynMembershipFIQL); if (!dynMembershipCond.isValid()) { SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression); @@ -98,13 +55,19 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen throw sce; } - DynGroupMembership dynMembership; - if (group.getDynMembership() == null) { - dynMembership = entityFactory.newEntity(DynGroupMembership.class); + DynGroupMembership<?> dynMembership; + if (anyTypeKind == AnyTypeKind.ANY_OBJECT && group.getADynMembership() == null) { + dynMembership = entityFactory.newEntity(ADynGroupMembership.class); dynMembership.setGroup(group); - group.setDynMembership(dynMembership); + group.setADynMembership((ADynGroupMembership) dynMembership); + } else if (anyTypeKind == AnyTypeKind.USER && group.getUDynMembership() == null) { + dynMembership = entityFactory.newEntity(UDynGroupMembership.class); + dynMembership.setGroup(group); + group.setUDynMembership((UDynGroupMembership) dynMembership); } else { - dynMembership = group.getDynMembership(); + dynMembership = anyTypeKind == AnyTypeKind.ANY_OBJECT + ? group.getADynMembership() + : group.getUDynMembership(); } dynMembership.setFIQLCond(dynMembershipFIQL); } @@ -123,16 +86,8 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen group.setName(groupTO.getName()); } - // attribute templates - setAttrTemplates(group, groupTO.getGPlainAttrTemplates(), GPlainAttrTemplate.class, GPlainSchema.class); - setAttrTemplates(group, groupTO.getGDerAttrTemplates(), GDerAttrTemplate.class, GDerSchema.class); - setAttrTemplates(group, groupTO.getGVirAttrTemplates(), GVirAttrTemplate.class, GVirSchema.class); - setAttrTemplates(group, groupTO.getMPlainAttrTemplates(), MPlainAttrTemplate.class, MPlainSchema.class); - setAttrTemplates(group, groupTO.getMDerAttrTemplates(), MDerAttrTemplate.class, MDerSchema.class); - setAttrTemplates(group, groupTO.getMVirAttrTemplates(), MVirAttrTemplate.class, MVirSchema.class); - // attributes, derived attributes, virtual attributes and resources - fill(group, groupTO, attrUtilsFactory.getInstance(AttributableType.GROUP), scce); + fill(group, groupTO, anyUtilsFactory.getInstance(AnyTypeKind.GROUP), scce); // owner if (groupTO.getUserOwner() != null) { @@ -152,8 +107,11 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen } } - if (groupTO.getDynMembershipCond() != null) { - setDynMembership(group, groupTO.getDynMembershipCond()); + if (groupTO.getADynMembershipCond() != null) { + setDynMembership(group, AnyTypeKind.ANY_OBJECT, groupTO.getADynMembershipCond()); + } + if (groupTO.getADynMembershipCond() != null) { + setDynMembership(group, AnyTypeKind.USER, groupTO.getUDynMembershipCond()); } return group; @@ -169,7 +127,7 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen SyncopeClientCompositeException scce = SyncopeClientException.buildComposite(); // fetch account ids before update - Map<String, String> oldAccountIds = getAccountIds(group, AttributableType.GROUP); + Map<String, String> oldConnObjectKeys = getConnObjectKeys(group); // realm setRealm(group, groupMod); @@ -180,26 +138,6 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen group.setName(groupMod.getName()); } - // attribute templates - if (groupMod.isModGAttrTemplates()) { - setAttrTemplates(group, groupMod.getGPlainAttrTemplates(), GPlainAttrTemplate.class, GPlainSchema.class); - } - if (groupMod.isModGDerAttrTemplates()) { - setAttrTemplates(group, groupMod.getGDerAttrTemplates(), GDerAttrTemplate.class, GDerSchema.class); - } - if (groupMod.isModGVirAttrTemplates()) { - setAttrTemplates(group, groupMod.getGVirAttrTemplates(), GVirAttrTemplate.class, GVirSchema.class); - } - if (groupMod.isModMAttrTemplates()) { - setAttrTemplates(group, groupMod.getMPlainAttrTemplates(), MPlainAttrTemplate.class, MPlainSchema.class); - } - if (groupMod.isModMDerAttrTemplates()) { - setAttrTemplates(group, groupMod.getMDerAttrTemplates(), MDerAttrTemplate.class, MDerSchema.class); - } - if (groupMod.isModMVirAttrTemplates()) { - setAttrTemplates(group, groupMod.getMVirAttrTemplates(), MVirAttrTemplate.class, MVirSchema.class); - } - // owner if (groupMod.getUserOwner() != null) { group.setUserOwner(groupMod.getUserOwner().getKey() == null @@ -213,13 +151,13 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen } // attributes, derived attributes, virtual attributes and resources - propByRes.merge(fill(group, groupMod, attrUtilsFactory.getInstance(AttributableType.GROUP), scce)); + propByRes.merge(fill(group, groupMod, anyUtilsFactory.getInstance(AnyTypeKind.GROUP), scce)); // check if some account id was changed by the update above - Map<String, String> newAccountIds = getAccountIds(group, AttributableType.GROUP); - for (Map.Entry<String, String> entry : oldAccountIds.entrySet()) { - if (newAccountIds.containsKey(entry.getKey()) - && !entry.getValue().equals(newAccountIds.get(entry.getKey()))) { + Map<String, String> newConnObjectKeys = getConnObjectKeys(group); + for (Map.Entry<String, String> entry : oldConnObjectKeys.entrySet()) { + if (newConnObjectKeys.containsKey(entry.getKey()) + && !entry.getValue().equals(newConnObjectKeys.get(entry.getKey()))) { propByRes.addOldAccountId(entry.getKey(), entry.getValue()); propByRes.add(ResourceOperation.UPDATE, entry.getKey()); @@ -227,15 +165,25 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen } // dynamic membership - if (group.getDynMembership() != null && groupMod.getDynMembershipCond() == null) { - group.setDynMembership(null); - } else if (group.getDynMembership() == null && groupMod.getDynMembershipCond() != null) { - setDynMembership(group, groupMod.getDynMembershipCond()); - } else if (group.getDynMembership() != null && groupMod.getDynMembershipCond() != null - && !group.getDynMembership().getFIQLCond().equals(groupMod.getDynMembershipCond())) { - - group.getDynMembership().getUsers().clear(); - setDynMembership(group, groupMod.getDynMembershipCond()); + if (group.getADynMembership() != null && groupMod.getADynMembershipCond() == null) { + group.setADynMembership(null); + } else if (group.getADynMembership() == null && groupMod.getADynMembershipCond() != null) { + setDynMembership(group, AnyTypeKind.ANY_OBJECT, groupMod.getADynMembershipCond()); + } else if (group.getADynMembership() != null && groupMod.getADynMembershipCond() != null + && !group.getADynMembership().getFIQLCond().equals(groupMod.getADynMembershipCond())) { + + group.getADynMembership().getMembers().clear(); + setDynMembership(group, AnyTypeKind.ANY_OBJECT, groupMod.getADynMembershipCond()); + } + if (group.getUDynMembership() != null && groupMod.getUDynMembershipCond() == null) { + group.setUDynMembership(null); + } else if (group.getUDynMembership() == null && groupMod.getUDynMembershipCond() != null) { + setDynMembership(group, AnyTypeKind.USER, groupMod.getUDynMembershipCond()); + } else if (group.getUDynMembership() != null && groupMod.getUDynMembershipCond() != null + && !group.getUDynMembership().getFIQLCond().equals(groupMod.getUDynMembershipCond())) { + + group.getUDynMembership().getMembers().clear(); + setDynMembership(group, AnyTypeKind.USER, groupMod.getUDynMembershipCond()); } return propByRes; @@ -245,7 +193,7 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen @Transactional(readOnly = true) @Override public GroupTO getGroupTO(final Group group) { - connObjectUtils.retrieveVirAttrValues(group, attrUtilsFactory.getInstance(AttributableType.GROUP)); + connObjectUtils.retrieveVirAttrValues(group); GroupTO groupTO = new GroupTO(); @@ -268,27 +216,11 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen fillTO(groupTO, group.getRealm().getFullPath(), group.getPlainAttrs(), group.getDerAttrs(), group.getVirAttrs(), group.getResources()); - for (GPlainAttrTemplate template : group.getAttrTemplates(GPlainAttrTemplate.class)) { - groupTO.getGPlainAttrTemplates().add(template.getSchema().getKey()); + if (group.getADynMembership() != null) { + groupTO.setADynMembershipCond(group.getADynMembership().getFIQLCond()); } - for (GDerAttrTemplate template : group.getAttrTemplates(GDerAttrTemplate.class)) { - groupTO.getGDerAttrTemplates().add(template.getSchema().getKey()); - } - for (GVirAttrTemplate template : group.getAttrTemplates(GVirAttrTemplate.class)) { - groupTO.getGVirAttrTemplates().add(template.getSchema().getKey()); - } - for (MPlainAttrTemplate template : group.getAttrTemplates(MPlainAttrTemplate.class)) { - groupTO.getMPlainAttrTemplates().add(template.getSchema().getKey()); - } - for (MDerAttrTemplate template : group.getAttrTemplates(MDerAttrTemplate.class)) { - groupTO.getMDerAttrTemplates().add(template.getSchema().getKey()); - } - for (MVirAttrTemplate template : group.getAttrTemplates(MVirAttrTemplate.class)) { - groupTO.getMVirAttrTemplates().add(template.getSchema().getKey()); - } - - if (group.getDynMembership() != null) { - groupTO.setDynMembershipCond(group.getDynMembership().getFIQLCond()); + if (group.getUDynMembership() != null) { + groupTO.setUDynMembershipCond(group.getUDynMembership().getFIQLCond()); } return groupTO; @@ -297,6 +229,6 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen @Transactional(readOnly = true) @Override public GroupTO getGroupTO(final Long key) { - return getGroupTO(groupDAO.authFetch(key)); + return getGroupTO(groupDAO.authFind(key)); } }
