All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.unboundid.scim.sdk.SCIMQueryAttributes Maven / Gradle / Ivy

Go to download

The UnboundID SCIM SDK is a library that may be used to interact with various types of SCIM-enabled endpoints (such as the UnboundID server products) to perform lightweight, cloud-based identity management via the SCIM Protocol. See http://www.simplecloud.info for more information.

There is a newer version: 1.8.26
Show newest version
/*
 * 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.sdk;

import com.unboundid.scim.schema.AttributeDescriptor;
import com.unboundid.scim.schema.ResourceDescriptor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.unboundid.scim.sdk.SCIMConstants.SCHEMA_URI_UBID_LDAP;



/**
 * This class represents a list of query attributes taken from the attributes
 * query parameter. e.g. attributes=name.formatted,userName
 */
public class SCIMQueryAttributes
{
  /**
   * Indicates whether all attributes and sub-attributes are requested.
   */
  private final boolean allAttributesRequested;

  /**
   * Indicates whether debugsearchindex was requested.
   */
  private boolean debugSearchIndex = false;

  /**
   * The set of attributes and sub-attributes explicitly requested.
   */
  private final Map> descriptors;


  /**
   * Create a new instance of query attributes from their string representation.
   *
   * @param resourceDescriptor  The resource descriptor for the SCIM endpoint.
   * @param attributes     The attributes query parameter specifying the set of
   *                       attributes or sub-attributes requested, or null if
   *                       all attributes and sub-attributes are requested. The
   *                       attributes must be qualified by their
   *                       schema URI if they are not in the core schema.
   *
   * @throws InvalidResourceException  If one of the specified attributes does
   *                                   not exist.
   */
  public SCIMQueryAttributes(final ResourceDescriptor resourceDescriptor,
                             final String attributes)
      throws InvalidResourceException
  {
    descriptors  =
        new HashMap>();

    if (attributes == null)
    {
      allAttributesRequested = true;
    }
    else {
      allAttributesRequested = false;

      List attributeList;
      if (attributes.isEmpty())
      {
        attributeList = Collections.emptyList();
      }
      else
      {
        attributeList = Arrays.asList(attributes.split(","));
      }
      initializeDescriptors(resourceDescriptor, attributeList);
    }
  }


  /**
   * Create a new instance of query attributes from their string representation.
   *
   * @param resourceDescriptor  The resource descriptor for the SCIM endpoint.
   * @param attributes     The attributes query parameter specifying the set of
   *                       attributes or sub-attributes requested, or null if
   *                       all attributes and sub-attributes are requested. The
   *                       attributes must be qualified by their
   *                       schema URI if they are not in the core schema.
   *
   * @throws InvalidResourceException  If one of the specified attributes does
   *                                   not exist.
   */
  public SCIMQueryAttributes(final List attributes,
                             final ResourceDescriptor resourceDescriptor)
      throws InvalidResourceException
  {
    descriptors  =
        new HashMap>();

    if (attributes == null)
    {
      allAttributesRequested = true;
    }
    else {
      allAttributesRequested = false;
      initializeDescriptors(resourceDescriptor, attributes);
    }
  }


  /**
   * Create a new set of query attributes from the provided information.
   *
   * @param descriptors         The set of attributes and sub-attributes
   *                            explicitly requested, or {@code null} if all
   *                            attributes are requested.
   */
  public SCIMQueryAttributes(
      final Map> descriptors)
  {
    this.allAttributesRequested = (descriptors == null);
    this.descriptors = descriptors;
  }



  /**
   * Create a new set of query attributes from the provided information.
   *
   * @param descriptors         The set of attributes and sub-attributes
   *                            explicitly requested, or {@code null} if all
   *                            attributes are requested.
   * @param debugSearchIndex    Indicates whether debugsearchindex is requested.
   */
  private SCIMQueryAttributes(
      final Map> descriptors,
      final boolean debugSearchIndex)
  {
    this.allAttributesRequested = (descriptors == null);
    this.descriptors = descriptors;
    this.debugSearchIndex = debugSearchIndex;
  }



  /**
   * Determine whether all attributes and sub-attributes are requested by
   * these query attributes.
   *
   * @return  {@code true} if all attributes and sub-attributes are requested,
   *          and {@code false} otherwise.
   */
  public boolean allAttributesRequested()
  {
    return allAttributesRequested;
  }



  /**
   * Determine whether debugsearchindex is requested by
   * these query attributes.
   *
   * @return  {@code true} if debugsearchindex is requested,
   *          and {@code false} otherwise.
   */
  public boolean isDebugSearchIndex()
  {
    return debugSearchIndex;
  }



  /**
   * Determine whether the specified attribute is requested by these query
   * attributes.
   *
   * @param attributeDescriptor  The attribute for which to make the
   *                             determination.
   *
   * @return  {@code true} if the specified attribute is requested, or false
   *          otherwise.
   */
  public boolean isAttributeRequested(
      final AttributeDescriptor attributeDescriptor)
  {
    return allAttributesRequested() ||
           descriptors.containsKey(attributeDescriptor);
  }



  /**
   * Returns the map of requested attributes and sub-attributes.
   *
   * @return an unmodifiable map of the requested attributes.
   */
  public Map> getDescriptors()
  {
    return Collections.unmodifiableMap(descriptors);
  }



  /**
   * Pare down a SCIM object to its requested attributes.
   *
   * @param scimObject  The SCIM object to be pared down.
   *
   * @return  The pared down SCIM object.
   */
  public SCIMObject pareObject(final SCIMObject scimObject)
  {
    if (allAttributesRequested())
    {
      return scimObject;
    }

    final SCIMObject paredObject = new SCIMObject();
    for (final Map.Entry> entry :
        descriptors.entrySet())
    {
      final AttributeDescriptor attributeDescriptor = entry.getKey();

      final SCIMAttribute a =
          scimObject.getAttribute(attributeDescriptor.getSchema(),
                                  attributeDescriptor.getName());
      if (a != null)
      {
        final SCIMAttribute paredAttribute = pareAttribute(a);
        if (paredAttribute != null)
        {
          paredObject.addAttribute(paredAttribute);
        }
      }
    }

    return paredObject;
  }



  /**
   * Pare down an attribute to its requested sub-attributes.
   *
   * @param attribute  The attribute to be pared down.
   *
   * @return  The pared down attribute, or {@code null} if the attribute
   *          should not be included at all.
   */
  public SCIMAttribute pareAttribute(final SCIMAttribute attribute)
  {
    final AttributeDescriptor descriptor = attribute.getAttributeDescriptor();

    if (allAttributesRequested() || descriptor.getSubAttributes() == null)
    {
      return attribute;
    }

    final Set subDescriptors = descriptors.get(descriptor);
    if (subDescriptors == null)
    {
      return null;
    }

    if (subDescriptors.isEmpty())
    {
      return attribute;
    }

    if (attribute.getAttributeDescriptor().isMultiValued())
    {
      final ArrayList values =
          new ArrayList();

      for (final SCIMAttributeValue v : attribute.getValues())
      {
        final ArrayList subAttributes =
            new ArrayList();
        for (final AttributeDescriptor d : subDescriptors)
        {
          final SCIMAttribute subAttribute = v.getAttribute(d.getName());
          if (subAttribute != null)
          {
            subAttributes.add(subAttribute);
          }
        }
        values.add(SCIMAttributeValue.createComplexValue(subAttributes));
      }

      return SCIMAttribute.create(
          descriptor, values.toArray(new SCIMAttributeValue[values.size()]));
    }
    else
    {
      final ArrayList subAttributes =
          new ArrayList();
      for (final AttributeDescriptor d : subDescriptors)
      {
        final SCIMAttribute subAttribute =
            attribute.getValue().getAttribute(d.getName());
        if (subAttribute != null)
        {
          subAttributes.add(subAttribute);
        }
      }
      return SCIMAttribute.create(descriptor,
          SCIMAttributeValue.createComplexValue(subAttributes));
    }
  }



  /**
   * Return query attributes formed by merging these query attributes with the
   * provided query attributes.
   *
   * @param that  The query attributes to be merged with these query attributes
   *              to form new query attributes.
   *
   * @return  The merged query attributes.
   *
   * @throws InvalidResourceException  If the query attributes could not be
   *                                   merged.
   */
  public SCIMQueryAttributes merge(final SCIMQueryAttributes that)
      throws InvalidResourceException
  {
    if (this.allAttributesRequested || that.allAttributesRequested)
    {
      return new SCIMQueryAttributes(null);
    }

    final Map> merged =
        new HashMap>(
            this.descriptors);

    for (final Map.Entry> e :
        that.descriptors.entrySet())
    {
      final AttributeDescriptor attributeDescriptor = e.getKey();
      final Set thatSet = e.getValue();

      Set thisSet = merged.get(attributeDescriptor);
      if (thisSet == null)
      {
        merged.put(attributeDescriptor, thatSet);
      }
      else
      {
        if (!thisSet.isEmpty())
        {
          if (thatSet.isEmpty())
          {
            thisSet.clear();
          }
          else
          {
            thisSet.addAll(thatSet);
          }
        }
      }
    }

    return new SCIMQueryAttributes(
        merged, this.debugSearchIndex || that.debugSearchIndex);
  }



  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    final StringBuilder sb = new StringBuilder("SCIMQueryAttributes{");
    sb.append("allAttributesRequested=").append(allAttributesRequested);
    sb.append(", debugSearchIndex=").append(debugSearchIndex);
    sb.append(", descriptors=").append(descriptors);
    sb.append('}');
    return sb.toString();
  }



  /**
   * Common code to initialize attribute descriptors for all requested
   * attributes.
   * @param resourceDescriptor  The resource descriptor for the SCIM endpoint.
   * @param attributes          List of requested attributes.
   * @throws InvalidResourceException  If one of the specified attributes does
   *                                   not exist.
   */
  private void initializeDescriptors(
      final ResourceDescriptor resourceDescriptor,
      final List attributes) throws InvalidResourceException
  {
    for (final String a : attributes)
    {
      if (a.equalsIgnoreCase("debugsearchindex"))
      {
        debugSearchIndex = true;
        continue;
      }

      final AttributePath path;
      if (resourceDescriptor.getSchema().equalsIgnoreCase(
          SCHEMA_URI_UBID_LDAP))
      {
        path = AttributePath.parse(a, resourceDescriptor.getSchema());
      }
      else
      {
        path = AttributePath.parse(a);
      }

      final AttributeDescriptor attributeDescriptor =
          resourceDescriptor.getAttribute(path.getAttributeSchema(),
              path.getAttributeName());

      Set subAttributes =
          descriptors.get(attributeDescriptor);
      if (subAttributes == null)
      {
        subAttributes = new HashSet();
        if (path.getSubAttributeName() != null)
        {
          subAttributes.add(
              attributeDescriptor.getSubAttribute(
                  path.getSubAttributeName()));
        }
        descriptors.put(attributeDescriptor, subAttributes);
      }
      else
      {
        if (!subAttributes.isEmpty())
        {
          if (path.getSubAttributeName() != null)
          {
            subAttributes.add(
                attributeDescriptor.getSubAttribute(
                    path.getSubAttributeName()));
          }
          else
          {
            subAttributes.clear();
          }
        }
      }
    }

    final AttributeDescriptor id =
        resourceDescriptor.getAttribute(SCIMConstants.SCHEMA_URI_CORE, "id");
    if (!descriptors.containsKey(id))
    {
      descriptors.put(id, new HashSet());
    }

    final AttributeDescriptor meta =
        resourceDescriptor.getAttribute(SCIMConstants.SCHEMA_URI_CORE,
            "meta");
    if (!descriptors.containsKey(meta))
    {
      descriptors.put(meta, new HashSet());
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy