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

com.unboundid.ldap.sdk.transformations.ExcludeEntryTransformation Maven / Gradle / Ivy

/*
 * Copyright 2016-2017 UnboundID Corp.
 * All Rights Reserved.
 */
/*
 * Copyright (C) 2016-2017 UnboundID Corp.
 *
 * 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.ldap.sdk.transformations;



import java.io.Serializable;
import java.util.concurrent.atomic.AtomicLong;

import com.unboundid.ldap.sdk.DN;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.Filter;
import com.unboundid.ldap.sdk.SearchScope;
import com.unboundid.ldap.sdk.schema.Schema;
import com.unboundid.util.Debug;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;



/**
 * This class provides an implementation of an entry transformation that will
 * return {@code null} for any entry that matches (or alternately, does not
 * match) a given set of criteria and should therefore be excluded from the data
 * set.
 */
@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
public final class ExcludeEntryTransformation
       implements EntryTransformation, Serializable
{
  /**
   * The serial version UID for this serializable class.
   */
  private static final long serialVersionUID = 103514669827637043L;



  // An optional counter that will be incremented for each entry that has been
  // excluded.
  private final AtomicLong excludedCount;

  // Indicates whether we need to check entries against the filter.
  private final boolean allEntriesMatchFilter;

  // Indicates whether we need to check entries against the scope.
  private final boolean allEntriesAreInScope;

  // Indicates whether to exclude entries that match the criteria, or to exclude
  // entries that do no not match the criteria.
  private final boolean excludeMatching;

  // The base DN to use to identify entries to exclude.
  private final DN baseDN;

  // The filter to use to identify entries to exclude.
  private final Filter filter;

  // The schema to use when processing.
  private final Schema schema;

  // The scope to use to identify entries to exclude.
  private final SearchScope scope;



  /**
   * Creates a new exclude entry transformation with the provided information.
   *
   * @param  schema           The schema to use in processing.  It may be
   *                          {@code null} if a default standard schema should
   *                          be used.
   * @param  baseDN           The base DN to use to identify which entries to
   *                          suppress.  If this is {@code null}, it will be
   *                          assumed to be the null DN.
   * @param  scope            The scope to use to identify which entries to
   *                          suppress.  If this is {@code null}, it will be
   *                          assumed to be {@link SearchScope#SUB}.
   * @param  filter           An optional filter to use to identify which
   *                          entries to suppress.  If this is {@code null},
   *                          then a default LDAP true filter (which will match
   *                          any entry) will be used.
   * @param  excludeMatching  Indicates whether to exclude entries that match
   *                          the criteria (if {@code true}) or to exclude
   *                          entries that do not match the criteria (if
   *                          {@code false}).
   * @param  excludedCount    An optional counter that will be incremented for
   *                          each entry that is excluded.
   */
  public ExcludeEntryTransformation(final Schema schema, final DN baseDN,
                                    final SearchScope scope,
                                    final Filter filter,
                                    final boolean excludeMatching,
                                    final AtomicLong excludedCount)
  {
    this.excludeMatching = excludeMatching;
    this.excludedCount = excludedCount;


    // If a schema was provided, then use it.  Otherwise, use the default
    // standard schema.
    Schema s = schema;
    if (s == null)
    {
      try
      {
        s = Schema.getDefaultStandardSchema();
      }
      catch (final Exception e)
      {
        // This should never happen.
        Debug.debugException(e);
      }
    }
    this.schema = s;


    // If a base DN was provided, then use it.  Otherwise, use the null DN.
    if (baseDN == null)
    {
      this.baseDN = DN.NULL_DN;
    }
    else
    {
      this.baseDN = baseDN;
    }


    // If a scope was provided, then use it.  Otherwise, use a subtree scope.
    if (scope == null)
    {
      this.scope = SearchScope.SUB;
    }
    else
    {
      this.scope = scope;
    }
    allEntriesAreInScope =
         (this.baseDN.isNullDN() && (this.scope == SearchScope.SUB));


    // If a filter was provided, then use it.  Otherwise, use an LDAP true
    // filter.
    if (filter == null)
    {
      this.filter = Filter.createANDFilter();
      allEntriesMatchFilter = true;
    }
    else
    {
      this.filter = filter;
      if (filter.getFilterType() == Filter.FILTER_TYPE_AND)
      {
        allEntriesMatchFilter = (filter.getComponents().length == 0);
      }
      else
      {
        allEntriesMatchFilter = false;
      }
    }
  }



  /**
   * {@inheritDoc}
   */
  public Entry transformEntry(final Entry e)
  {
    if (e == null)
    {
      return null;
    }


    // Determine whether the entry is within the configured scope.
    boolean matchesScope;
    try
    {
      matchesScope =
           (allEntriesAreInScope || e.matchesBaseAndScope(baseDN, scope));
    }
    catch (final Exception ex)
    {
      Debug.debugException(ex);

      // This should only happen if the entry has a malformed DN.  In that
      // case, we'll say that it doesn't match the scope.
      matchesScope = false;
    }


    // Determine whether the entry matches the suppression filter.
    boolean matchesFilter;
    try
    {
      matchesFilter = (allEntriesMatchFilter || filter.matchesEntry(e, schema));
    }
    catch (final Exception ex)
    {
      Debug.debugException(ex);

      // This should only happen if the filter is one that we can't process at
      // all or against the target entry.  In that case, we'll say that it
      // doesn't match the filter.
      matchesFilter = false;
    }


    if (matchesScope && matchesFilter)
    {
      if (excludeMatching)
      {
        if (excludedCount != null)
        {
          excludedCount.incrementAndGet();
        }
        return null;
      }
      else
      {
        return e;
      }
    }
    else
    {
      if (excludeMatching)
      {
        return e;
      }
      else
      {
        if (excludedCount != null)
        {
          excludedCount.incrementAndGet();
        }
        return null;
      }
    }
  }



  /**
   * {@inheritDoc}
   */
  public Entry translate(final Entry original, final long firstLineNumber)
  {
    return transformEntry(original);
  }



  /**
   * {@inheritDoc}
   */
  public Entry translateEntryToWrite(final Entry original)
  {
    return transformEntry(original);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy