![JAR search and dependency download from the Maven repository](/logo.png)
com.unboundid.scim.ldap.MultiValuedAttributeMapper Maven / Gradle / Ivy
/*
* Copyright 2011-2019 Ping Identity Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (GPLv2 only)
* or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*/
package com.unboundid.scim.ldap;
import com.unboundid.asn1.ASN1OctetString;
import com.unboundid.ldap.sdk.Attribute;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.Filter;
import com.unboundid.ldap.sdk.controls.ServerSideSortRequestControl;
import com.unboundid.ldap.sdk.controls.SortKey;
import com.unboundid.scim.schema.AttributeDescriptor;
import com.unboundid.scim.sdk.AttributePath;
import com.unboundid.scim.sdk.InvalidResourceException;
import com.unboundid.scim.sdk.SCIMAttribute;
import com.unboundid.scim.sdk.SCIMAttributeValue;
import com.unboundid.scim.sdk.SCIMObject;
import com.unboundid.scim.sdk.SCIMFilter;
import com.unboundid.scim.sdk.SCIMFilterType;
import com.unboundid.scim.sdk.SortParameters;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* This class provides an attribute mapper for multi-valued attributes.
* Each type of value (e.g. "work", "home") is mapped to one or more
* single-valued LDAP attributes, where each LDAP attribute holds one
* of the SCIM sub-attributes.
*/
public class MultiValuedAttributeMapper extends AttributeMapper
{
/**
* A set of value mappers for each value of the "type" sub-attribute.
*/
private final Map valueMappers;
/**
* The set of LDAP attributes that are mapped by this attribute mapper.
*/
private final Set ldapAttributeTypes;
/**
* Create a new instance of a complex attribute mapper.
*
* @param attributeDescriptor The SCIM attribute type that is mapped by this
* attribute mapper.
* @param canonicalValueMappers The set of complex value mappers for this
* attribute mapper.
*/
public MultiValuedAttributeMapper(
final AttributeDescriptor attributeDescriptor,
final Collection canonicalValueMappers)
{
super(attributeDescriptor);
ldapAttributeTypes = new HashSet();
valueMappers = new HashMap();
for (final CanonicalValueMapper canonicalValueMapper :
canonicalValueMappers)
{
valueMappers.put(canonicalValueMapper.getTypeValue(),
canonicalValueMapper);
for (final SubAttributeTransformation sat :
canonicalValueMapper.getTransformations())
{
ldapAttributeTypes.add(
sat.getAttributeTransformation().getLdapAttribute());
}
}
}
/**
* {@inheritDoc}
*/
@Override
public Set getLDAPAttributeTypes()
{
return ldapAttributeTypes;
}
/**
* {@inheritDoc}
*/
@Override
public Filter toLDAPFilter(final SCIMFilter filter)
throws InvalidResourceException
{
final SCIMFilterType type = filter.getFilterType();
List ldapFilterTypes = null;
List ldapFilterValues = null;
if(type != SCIMFilterType.AND && type != SCIMFilterType.OR)
{
String subAttributeName =
filter.getFilterAttribute().getSubAttributeName();
if (subAttributeName == null)
{
subAttributeName = "value";
}
final List selectedTransformations =
new ArrayList();
for (final CanonicalValueMapper canonicalValueMapper :
valueMappers.values())
{
for (final SubAttributeTransformation sat :
canonicalValueMapper.getTransformations())
{
if (sat.getSubAttribute().equalsIgnoreCase(subAttributeName))
{
selectedTransformations.add(sat);
}
}
}
if (selectedTransformations.isEmpty())
{
getAttributeDescriptor().getSubAttribute(subAttributeName);
return null; //match nothing
}
ldapFilterTypes = new ArrayList(selectedTransformations.size());
ldapFilterValues = new ArrayList(selectedTransformations.size());
for (final SubAttributeTransformation sat : selectedTransformations)
{
final AttributeTransformation at = sat.getAttributeTransformation();
final String filterValue;
if (filter.getFilterValue() != null)
{
filterValue = at.getTransformation().toLDAPFilterValue(
filter.getFilterValue());
}
else
{
filterValue = null;
}
ldapFilterTypes.add(at.getLdapAttribute());
ldapFilterValues.add(filterValue);
}
}
else
{
// We don't have to worry about AND and OR filter types since they are
// handled earlier by the resource mapper.
throw new RuntimeException("Invalid filter type: " + type);
}
final List filterComponents =
new ArrayList(ldapFilterTypes.size());
for (int i = 0; i < ldapFilterTypes.size(); i++)
{
final String ldapAttributeType = ldapFilterTypes.get(i);
final String ldapFilterValue = ldapFilterValues.get(i);
switch (type)
{
case EQUALITY:
{
filterComponents.add(
Filter.createEqualityFilter(ldapAttributeType,
ldapFilterValue));
}
break;
case CONTAINS:
{
filterComponents.add(
Filter.createSubstringFilter(ldapAttributeType,
null,
new String[] { ldapFilterValue },
null));
}
break;
case STARTS_WITH:
{
filterComponents.add(
Filter.createSubstringFilter(ldapAttributeType,
ldapFilterValue,
null,
null));
}
break;
case PRESENCE:
{
filterComponents.add(Filter.createPresenceFilter(ldapAttributeType));
}
break;
case GREATER_THAN:
{
return Filter.createANDFilter(
Filter.createGreaterOrEqualFilter(ldapAttributeType, ldapFilterValue),
Filter.createNOTFilter(
Filter.createEqualityFilter(ldapAttributeType, ldapFilterValue)));
}
case GREATER_OR_EQUAL:
{
return Filter.createGreaterOrEqualFilter(ldapAttributeType,
ldapFilterValue);
}
case LESS_THAN:
{
return Filter.createANDFilter(
Filter.createLessOrEqualFilter(ldapAttributeType, ldapFilterValue),
Filter.createNOTFilter(
Filter.createEqualityFilter(ldapAttributeType, ldapFilterValue)));
}
case LESS_OR_EQUAL:
{
return Filter.createLessOrEqualFilter(ldapAttributeType,
ldapFilterValue);
}
default:
throw new RuntimeException(
"Filter type " + type + " is not supported");
}
}
if (filterComponents.size() == 1)
{
return filterComponents.get(0);
}
else
{
return Filter.createORFilter(filterComponents);
}
}
@Override
public Set toLDAPAttributeTypes(final AttributePath scimAttribute)
throws InvalidResourceException
{
String subAttributeName = scimAttribute.getSubAttributeName();
if (subAttributeName == null)
{
subAttributeName = "value";
}
final List selectedTransformations =
new ArrayList();
for (final CanonicalValueMapper canonicalValueMapper :
valueMappers.values())
{
for (final SubAttributeTransformation sat :
canonicalValueMapper.getTransformations())
{
if (sat.getSubAttribute().equalsIgnoreCase(subAttributeName))
{
selectedTransformations.add(sat);
}
}
}
if (selectedTransformations.isEmpty())
{
getAttributeDescriptor().getSubAttribute(subAttributeName);
return Collections.emptySet();
}
Set ldapAttrTypes =
new LinkedHashSet(selectedTransformations.size());
for (final SubAttributeTransformation sat : selectedTransformations)
{
final AttributeTransformation at = sat.getAttributeTransformation();
ldapAttrTypes.add(at.getLdapAttribute());
}
return ldapAttrTypes;
}
/**
* {@inheritDoc}
*/
@Override
public ServerSideSortRequestControl toLDAPSortControl(
final SortParameters sortParameters)
throws InvalidResourceException
{
String subAttributeName = sortParameters.getSortBy().getSubAttributeName();
if (subAttributeName == null)
{
subAttributeName = "value";
}
SubAttributeTransformation selectedTransformation = null;
for (final CanonicalValueMapper canonicalValueMapper :
valueMappers.values())
{
for (final SubAttributeTransformation sat :
canonicalValueMapper.getTransformations())
{
if (sat.getSubAttribute().equalsIgnoreCase(subAttributeName))
{
selectedTransformation = sat;
break;
}
}
if(selectedTransformation != null)
{
break;
}
}
if (selectedTransformation == null)
{
// Make sure the sub-attribute is defined
getAttributeDescriptor().getSubAttribute(subAttributeName);
throw new InvalidResourceException("Cannot sort by attribute " +
sortParameters.getSortBy() + " because it has no mapping");
}
final AttributeTransformation attributeTransformation =
selectedTransformation.getAttributeTransformation();
if(attributeTransformation.getTransformation()
instanceof DefaultTransformation)
{
final AttributeDescriptor subAttributeDescriptor =
getAttributeDescriptor().getSubAttribute(subAttributeName);
final boolean reverseOrder = !sortParameters.isAscendingOrder();
if(subAttributeDescriptor.getDataType() ==
AttributeDescriptor.DataType.STRING)
{
return new ServerSideSortRequestControl(
new SortKey(attributeTransformation.getLdapAttribute(),
subAttributeDescriptor.isCaseExact() ?
CASE_EXACT_OMR_OID : CASE_IGNORE_OMR_OID, reverseOrder));
}
return new ServerSideSortRequestControl(
new SortKey(attributeTransformation.getLdapAttribute(),
reverseOrder));
}
else
{
throw new InvalidResourceException("Cannot sort by attribute " +
sortParameters.getSortBy() + " because it is mapped with custom " +
"transformations");
}
}
/**
* {@inheritDoc}
*/
@Override
public void toLDAPAttributes(final SCIMObject scimObject,
final Collection attributes)
throws InvalidResourceException {
final SCIMAttribute scimAttribute =
scimObject.getAttribute(getAttributeDescriptor().getSchema(),
getAttributeDescriptor().getName());
if (scimAttribute != null)
{
for (SCIMAttributeValue v : scimAttribute.getValues())
{
final SCIMAttribute typeAttr = v.getAttribute("type");
CanonicalValueMapper canonicalValueMapper = null;
if (typeAttr != null)
{
final String type = typeAttr.getValue().getStringValue();
canonicalValueMapper = valueMappers.get(type);
}
// Check for a default mapper.
if (canonicalValueMapper == null)
{
canonicalValueMapper = valueMappers.get(null);
}
if (canonicalValueMapper != null)
{
for (final SubAttributeTransformation sat :
canonicalValueMapper.getTransformations())
{
final AttributeTransformation at = sat.getAttributeTransformation();
final String scimType = sat.getSubAttribute();
final String ldapType = at.getLdapAttribute();
final SCIMAttribute subAttribute = v.getAttribute(scimType);
if (subAttribute != null)
{
final AttributeDescriptor subDescriptor =
getAttributeDescriptor().getSubAttribute(scimType);
final ASN1OctetString value = at.getTransformation().toLDAPValue(
subDescriptor, subAttribute.getValue());
attributes.add(new Attribute(ldapType, value));
}
}
}
}
}
}
/**
* {@inheritDoc}
*/
@Override
public SCIMAttribute toSCIMAttribute(final Entry entry)
throws InvalidResourceException {
final List values = new ArrayList();
for (final CanonicalValueMapper canonicalValueMapper :
valueMappers.values())
{
if (canonicalValueMapper.getTypeValue() != null)
{
final List subAttributes =
new ArrayList();
for (final SubAttributeTransformation sat :
canonicalValueMapper.getTransformations())
{
final AttributeTransformation at = sat.getAttributeTransformation();
final String scimType = sat.getSubAttribute();
final String ldapType = at.getLdapAttribute();
final AttributeDescriptor subDescriptor =
getAttributeDescriptor().getSubAttribute(scimType);
final Attribute a = entry.getAttribute(ldapType);
if (a != null)
{
final ASN1OctetString[] rawValues = a.getRawValues();
if (rawValues.length > 0)
{
final SCIMAttributeValue value =
at.getTransformation().toSCIMValue(subDescriptor,
rawValues[0]);
subAttributes.add(
SCIMAttribute.create(subDescriptor, value));
}
}
}
if (!subAttributes.isEmpty())
{
if (canonicalValueMapper.getTypeValue() != null)
{
subAttributes.add(SCIMAttribute.create(
getAttributeDescriptor().getSubAttribute("type"),
SCIMAttributeValue.createStringValue(
canonicalValueMapper.getTypeValue())));
}
final SCIMAttributeValue complexValue =
SCIMAttributeValue.createComplexValue(subAttributes);
values.add(complexValue);
}
}
else
{
if (canonicalValueMapper.getTransformations().size() > 0)
{
final SubAttributeTransformation sat =
canonicalValueMapper.getTransformations().iterator().next();
final AttributeTransformation at = sat.getAttributeTransformation();
final String scimType = sat.getSubAttribute();
final String ldapType = at.getLdapAttribute();
final Attribute a = entry.getAttribute(ldapType);
if (a != null)
{
for (final ASN1OctetString v : a.getRawValues())
{
final List subAttributes =
new ArrayList();
final AttributeDescriptor subDescriptor =
getAttributeDescriptor().getSubAttribute(scimType);
final SCIMAttributeValue scimValue =
at.getTransformation().toSCIMValue(subDescriptor, v);
subAttributes.add(SCIMAttribute.create(subDescriptor, scimValue));
final SCIMAttributeValue complexValue =
SCIMAttributeValue.createComplexValue(subAttributes);
values.add(complexValue);
}
}
}
}
}
if (values.isEmpty())
{
return null;
}
else
{
return SCIMAttribute.create(
getAttributeDescriptor(),
values.toArray(new SCIMAttributeValue[values.size()]));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy