001/*
002 * Copyright 2011-2018 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-2018 Ping Identity Corporation
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.ldap.sdk.unboundidds.extensions;
022
023
024
025import java.util.ArrayList;
026import java.util.Collection;
027import java.util.Collections;
028import java.util.Iterator;
029import java.util.List;
030
031import com.unboundid.asn1.ASN1Element;
032import com.unboundid.asn1.ASN1OctetString;
033import com.unboundid.asn1.ASN1Sequence;
034import com.unboundid.ldap.sdk.LDAPException;
035import com.unboundid.ldap.sdk.ResultCode;
036import com.unboundid.util.Debug;
037import com.unboundid.util.NotMutable;
038import com.unboundid.util.StaticUtils;
039import com.unboundid.util.ThreadSafety;
040import com.unboundid.util.ThreadSafetyLevel;
041import com.unboundid.util.Validator;
042
043import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*;
044
045
046
047/**
048 * This class provides an implementation of a get changelog batch change
049 * selection criteria value that indicates that the server should only return
050 * changes which target one or more of the specified attributes.  The changes
051 * may target other attributes as well, but at least one of the associated
052 * attributes must be included in the change.
053 * <BR>
054 * <BLOCKQUOTE>
055 *   <B>NOTE:</B>  This class, and other classes within the
056 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
057 *   supported for use against Ping Identity, UnboundID, and Alcatel-Lucent 8661
058 *   server products.  These classes provide support for proprietary
059 *   functionality or for external specifications that are not considered stable
060 *   or mature enough to be guaranteed to work in an interoperable way with
061 *   other types of LDAP servers.
062 * </BLOCKQUOTE>
063 */
064@NotMutable()
065@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
066public final class AnyAttributesChangeSelectionCriteria
067       extends ChangelogBatchChangeSelectionCriteria
068{
069  /**
070   * The inner BER type that should be used for encoded elements that represent
071   * an any attributes get changelog batch selection criteria value.
072   */
073  static final byte TYPE_SELECTION_CRITERIA_ANY_ATTRIBUTES = (byte) 0xA1;
074
075
076
077  // The names of the target attributes.
078  private final List<String> attributeNames;
079
080
081
082  /**
083   * Creates a new any attributes change selection criteria value with the
084   * provided set of attribute names.
085   *
086   * @param  attributeNames  The names of the target attributes for changes that
087   *                         should be retrieved.  It must not be {@code null}
088   *                         or empty.
089   */
090  public AnyAttributesChangeSelectionCriteria(final String... attributeNames)
091  {
092    this(StaticUtils.toList(attributeNames));
093  }
094
095
096
097  /**
098   * Creates a new any attributes change selection criteria value with the
099   * provided set of attribute names.
100   *
101   * @param  attributeNames  The names of the target attributes for changes that
102   *                         should be retrieved.  It must not be {@code null}
103   *                         or empty.
104   */
105  public AnyAttributesChangeSelectionCriteria(
106              final Collection<String> attributeNames)
107  {
108    Validator.ensureNotNull(attributeNames);
109    Validator.ensureFalse(attributeNames.isEmpty());
110
111    this.attributeNames =
112         Collections.unmodifiableList(new ArrayList<String>(attributeNames));
113  }
114
115
116
117  /**
118   * Decodes the provided ASN.1 element, which is the inner element of a
119   * changelog batch change selection criteria element, as an any attributes
120   * change selection criteria value.
121   *
122   * @param  innerElement  The inner element of a changelog batch change
123   *                       selection criteria element to be decoded.
124   *
125   * @return  The decoded any attributes change selection criteria value.
126   *
127   * @throws  LDAPException  If a problem is encountered while trying to decode
128   *                         the provided element as the inner element of an any
129   *                         attributes change selection criteria value.
130   */
131  static AnyAttributesChangeSelectionCriteria decodeInnerElement(
132              final ASN1Element innerElement)
133         throws LDAPException
134  {
135    try
136    {
137      final ASN1Element[] attrElements =
138           ASN1Sequence.decodeAsSequence(innerElement).elements();
139      final ArrayList<String> attrNames =
140           new ArrayList<String>(attrElements.length);
141      for (final ASN1Element e : attrElements)
142      {
143        attrNames.add(ASN1OctetString.decodeAsOctetString(e).stringValue());
144      }
145
146      return new AnyAttributesChangeSelectionCriteria(attrNames);
147    }
148    catch (final Exception e)
149    {
150      Debug.debugException(e);
151      throw new LDAPException(ResultCode.DECODING_ERROR,
152           ERR_ANY_ATTRS_CHANGE_SELECTION_CRITERIA_DECODE_ERROR.get(
153                StaticUtils.getExceptionMessage(e)),
154           e);
155    }
156  }
157
158
159
160  /**
161   * Retrieves the names of the target attributes for changes that should be
162   * retrieved.
163   *
164   * @return  The names of the target attributes for changes that should be
165   *          retrieved.
166   */
167  public List<String> getAttributeNames()
168  {
169    return attributeNames;
170  }
171
172
173
174  /**
175   * {@inheritDoc}
176   */
177  @Override()
178  public ASN1Element encodeInnerElement()
179  {
180    final ArrayList<ASN1Element> elements =
181         new ArrayList<ASN1Element>(attributeNames.size());
182    for (final String s : attributeNames)
183    {
184      elements.add(new ASN1OctetString(s));
185    }
186
187    return new ASN1Sequence(TYPE_SELECTION_CRITERIA_ANY_ATTRIBUTES, elements);
188  }
189
190
191
192  /**
193   * {@inheritDoc}
194   */
195  @Override()
196  public void toString(final StringBuilder buffer)
197  {
198    buffer.append("AnyAttributesChangeSelectionCriteria(attributeNames={");
199
200    final Iterator<String> iterator = attributeNames.iterator();
201    while (iterator.hasNext())
202    {
203      buffer.append(iterator.next());
204      if (iterator.hasNext())
205      {
206        buffer.append(',');
207      }
208    }
209
210    buffer.append("})");
211  }
212}