IdentityObjectSearchCriteria criteria) throws IdentityException
{
if (relationshipType != null && !relationshipType.getName().equals(MEMBERSHIP_TYPE))
{
throw new IdentityException("This store implementation supports only '" + MEMBERSHIP_TYPE +"' relationship type");
}
LDAPIdentityObjectImpl ldapIO = getSafeLDAPIO(ctx, identity);
LDAPIdentityObjectTypeConfiguration typeConfig = getTypeConfiguration(ctx, identity.getIdentityType());
LdapContext ldapContext = getLDAPContext(ctx);
List<IdentityObject> objects = new LinkedList<IdentityObject>();
try
{
// If parent simply look for all its members
if (parent)
{
if (typeConfig.getParentMembershipAttributeName() != null)
{
Attributes attrs = ldapContext.getAttributes(ldapIO.getDn());
Attribute member = attrs.get(typeConfig.getParentMembershipAttributeName());
if (member != null)
{
NamingEnumeration memberValues = member.getAll();
while (memberValues.hasMoreElements())
{
String memberRef = memberValues.nextElement().toString();
// Ignore placeholder value in memberships
String placeholder = typeConfig.getParentMembershipAttributePlaceholder();
if (placeholder != null && memberRef.equalsIgnoreCase(placeholder))
{
continue;
}
if (typeConfig.isParentMembershipAttributeDN())
{
//TODO: use direct LDAP query instead of other find method and add attributesFilter
if (criteria != null && criteria.getFilter() != null)
{
String name = Tools.stripDnToName(memberRef);
String regex = Tools.wildcardToRegex(criteria.getFilter());
if (Pattern.matches(regex, name))
{
objects.add(findIdentityObject(ctx, memberRef));
}
}
else
{
objects.add(findIdentityObject(ctx, memberRef));
}
}
else
{
//TODO: if relationships are not refered with DNs and only names its not possible to map
//TODO: them to proper IdentityType and keep name uniqnes per type. Workaround needed
throw new NotYetImplementedException("LDAP limitation. If relationship targets are not refered with FQDNs " +
"and only names, it's not possible to map them to proper IdentityType and keep name uniqnes per type. " +
"Workaround needed");
}
//break;
}
}
}
else
{
objects.addAll(findRelatedIdentityObjects(ctx, identity, ldapIO, criteria, false));
}
}
// if not parent then all parent entries need to be found
else
{
if (typeConfig.getChildMembershipAttributeName() == null)
{
objects.addAll(findRelatedIdentityObjects(ctx, identity, ldapIO, criteria, true));
}
else
{
Attributes attrs = ldapContext.getAttributes(ldapIO.getDn());
Attribute member = attrs.get(typeConfig.getChildMembershipAttributeName());
if (member != null)
{
NamingEnumeration memberValues = member.getAll();
while (memberValues.hasMoreElements())
{
String memberRef = memberValues.nextElement().toString();
if (typeConfig.isChildMembershipAttributeDN())
{
//TODO: use direct LDAP query instead of other find method and add attributesFilter
if (criteria != null && criteria.getFilter() != null)
{
String name = Tools.stripDnToName(memberRef);
String regex = Tools.wildcardToRegex(criteria.getFilter());
if (Pattern.matches(regex, name))
{
objects.add(findIdentityObject(ctx, memberRef));
}
}
else
{
objects.add(findIdentityObject(ctx, memberRef));
}
}
else
{
//TODO: if relationships are not refered with DNs and only names its not possible to map
//TODO: them to proper IdentityType and keep name uniqnes per type. Workaround needed
throw new NotYetImplementedException("LDAP limitation. If relationship targets are not refered with FQDNs " +
"and only names, it's not possible to map them to proper IdentityType and keep name uniqnes per type. " +
"Workaround needed");
}
//break;
}
}
}
}
}
catch (NamingException e)
{
throw new IdentityException("Failed to resolve relationship", e);
}
finally
{
try
{
ldapContext.close();
}
catch (NamingException e)
{
throw new IdentityException("Failed to close LDAP connection", e);
}
}
if (criteria != null && criteria.isPaged())
{