001/*
002 * Copyright 2009-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.logs;
022
023
024
025import java.util.Collections;
026import java.util.LinkedList;
027import java.util.List;
028import java.util.StringTokenizer;
029
030import com.unboundid.ldap.sdk.DereferencePolicy;
031import com.unboundid.ldap.sdk.Filter;
032import com.unboundid.ldap.sdk.SearchScope;
033import com.unboundid.util.Debug;
034import com.unboundid.util.NotExtensible;
035import com.unboundid.util.NotMutable;
036import com.unboundid.util.ThreadSafety;
037import com.unboundid.util.ThreadSafetyLevel;
038
039
040
041/**
042 * This class provides a data structure that holds information about a log
043 * message that may appear in the Directory Server access log about a search
044 * request received from a client.
045 * <BR>
046 * <BLOCKQUOTE>
047 *   <B>NOTE:</B>  This class, and other classes within the
048 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
049 *   supported for use against Ping Identity, UnboundID, and
050 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
051 *   for proprietary functionality or for external specifications that are not
052 *   considered stable or mature enough to be guaranteed to work in an
053 *   interoperable way with other types of LDAP servers.
054 * </BLOCKQUOTE>
055 */
056@NotExtensible()
057@NotMutable()
058@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
059public class SearchRequestAccessLogMessage
060       extends OperationRequestAccessLogMessage
061{
062  /**
063   * The serial version UID for this serializable class.
064   */
065  private static final long serialVersionUID = -6751258649156129642L;
066
067
068
069  // The typesOnly value for the search request.
070  private final Boolean typesOnly;
071
072  // The alias dereferencing policy for the search request.
073  private final DereferencePolicy derefPolicy;
074
075  // The size limit for the search request.
076  private final Integer sizeLimit;
077
078  // The time limit for the search request.
079  private final Integer timeLimit;
080
081  // The list of requested attributes for the search request.
082  private final List<String> requestedAttributes;
083
084  // The scope for the search request.
085  private final SearchScope scope;
086
087  // The base DN for the search request.
088  private final String baseDN;
089
090  // The string representation of the filter for the search request.
091  private final String filter;
092
093
094
095  /**
096   * Creates a new search request access log message from the provided message
097   * string.
098   *
099   * @param  s  The string to be parsed as a search request access log message.
100   *
101   * @throws  LogException  If the provided string cannot be parsed as a valid
102   *                        log message.
103   */
104  public SearchRequestAccessLogMessage(final String s)
105         throws LogException
106  {
107    this(new LogMessage(s));
108  }
109
110
111
112  /**
113   * Creates a new search request access log message from the provided log
114   * message.
115   *
116   * @param  m  The log message to be parsed as a search request access log
117   *            message.
118   */
119  public SearchRequestAccessLogMessage(final LogMessage m)
120  {
121    super(m);
122
123    baseDN    = getNamedValue("base");
124    filter    = getNamedValue("filter");
125    sizeLimit = getNamedValueAsInteger("sizeLimit");
126    timeLimit = getNamedValueAsInteger("timeLimit");
127    typesOnly = getNamedValueAsBoolean("typesOnly");
128
129    SearchScope ss = null;
130    try
131    {
132      ss = SearchScope.definedValueOf(getNamedValueAsInteger("scope"));
133    }
134    catch (final Exception e)
135    {
136      Debug.debugException(e);
137    }
138    scope = ss;
139
140    DereferencePolicy deref = null;
141    final String derefStr = getNamedValue("deref");
142    if (derefStr != null)
143    {
144      for (final DereferencePolicy p : DereferencePolicy.values())
145      {
146        if (p.getName().equalsIgnoreCase(derefStr))
147        {
148          deref = p;
149          break;
150        }
151      }
152    }
153    derefPolicy = deref;
154
155    final String attrStr = getNamedValue("attrs");
156    if (attrStr == null)
157    {
158      requestedAttributes = null;
159    }
160    else if (attrStr.equals("ALL"))
161    {
162      requestedAttributes = Collections.emptyList();
163    }
164    else
165    {
166      final LinkedList<String> attrs = new LinkedList<>();
167      final StringTokenizer st = new StringTokenizer(attrStr, ",", false);
168      while (st.hasMoreTokens())
169      {
170        attrs.add(st.nextToken());
171      }
172      requestedAttributes = Collections.unmodifiableList(attrs);
173    }
174  }
175
176
177
178  /**
179   * Retrieves the base DN for the search request.
180   *
181   * @return  The base DN for the search request, or {@code null} if it is not
182   *          included in the log message.
183   */
184  public final String getBaseDN()
185  {
186    return baseDN;
187  }
188
189
190
191  /**
192   * Retrieves the scope for the search request.
193   *
194   * @return  The scope for the search request, or {@code null} if it is not
195   *          included in the log message.
196   */
197  public final SearchScope getScope()
198  {
199    return scope;
200  }
201
202
203
204  /**
205   * Retrieves a string representation of the filter for the search request.
206   *
207   * @return  A string representation of the filter for the search request, or
208   *          {@code null} if it is not included in the log message.
209   */
210  public final String getFilter()
211  {
212    return filter;
213  }
214
215
216
217  /**
218   * Retrieves a parsed representation of the filter for the search request.
219   *
220   * @return  A parsed representation of the filter for the search request, or
221   *          {@code null} if it is not included in the log message or the
222   *          filter string cannot be parsed as a filter.
223   */
224  public final Filter getParsedFilter()
225  {
226    try
227    {
228      if (filter == null)
229      {
230        return null;
231      }
232      else
233      {
234        return Filter.create(filter);
235      }
236    }
237    catch (final Exception e)
238    {
239      Debug.debugException(e);
240      return null;
241    }
242  }
243
244
245
246  /**
247   * Retrieves the dereference policy for the search request.
248   *
249   * @return  The dereference policy for the search request, or {@code null} if
250   *          it is not included in the log message or the value cannot be
251   *          parsed as a valid {@code DereferencePolicy} value.
252   */
253  public final DereferencePolicy getDereferencePolicy()
254  {
255    return derefPolicy;
256  }
257
258
259
260  /**
261   * Retrieves the size limit for the search request.
262   *
263   * @return  The size limit for the search request, or {@code null} if it is
264   *          not included in the log message or the value cannot be parsed as
265   *          an integer.
266   */
267  public final Integer getSizeLimit()
268  {
269    return sizeLimit;
270  }
271
272
273
274  /**
275   * Retrieves the time limit for the search request.
276   *
277   * @return  The time limit for the search request, or {@code null} if it is
278   *          not included in the log message or the value cannot be parsed as
279   *          an integer.
280   */
281  public final Integer getTimeLimit()
282  {
283    return timeLimit;
284  }
285
286
287
288  /**
289   * Retrieves the typesOnly value for the search request.
290   *
291   * @return  {@code true} if only attribute type names should be included in
292   *          entries that are returned, {@code false} if both attribute types
293   *          and values should be returned, or {@code null} if is not included
294   *          in the log message or cannot be parsed as a Boolean.
295   */
296  public final Boolean typesOnly()
297  {
298    return typesOnly;
299  }
300
301
302
303  /**
304   * Retrieves the list of requested attributes for the search request.
305   *
306   * @return  The list of requested attributes for the search request, an empty
307   *          list if the client did not explicitly request any attributes, or
308   *          {@code null} if it is not included in the log message.
309   */
310  public final List<String> getRequestedAttributes()
311  {
312    return requestedAttributes;
313  }
314
315
316
317  /**
318   * {@inheritDoc}
319   */
320  @Override()
321  public final AccessLogOperationType getOperationType()
322  {
323    return AccessLogOperationType.SEARCH;
324  }
325}