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