001/* 002 * Copyright 2009-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2009-2024 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2009-2024 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk.unboundidds.logs; 037 038 039 040import java.util.Collections; 041import java.util.LinkedList; 042import java.util.List; 043import java.util.StringTokenizer; 044 045import com.unboundid.ldap.sdk.DereferencePolicy; 046import com.unboundid.ldap.sdk.Filter; 047import com.unboundid.ldap.sdk.SearchScope; 048import com.unboundid.util.Debug; 049import com.unboundid.util.NotExtensible; 050import com.unboundid.util.NotMutable; 051import com.unboundid.util.NotNull; 052import com.unboundid.util.Nullable; 053import com.unboundid.util.ThreadSafety; 054import com.unboundid.util.ThreadSafetyLevel; 055 056 057 058/** 059 * This class provides a data structure that holds information about a log 060 * message that may appear in the Directory Server access log about a search 061 * request received from a client. 062 * <BR> 063 * <BLOCKQUOTE> 064 * <B>NOTE:</B> This class, and other classes within the 065 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 066 * supported for use against Ping Identity, UnboundID, and 067 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 068 * for proprietary functionality or for external specifications that are not 069 * considered stable or mature enough to be guaranteed to work in an 070 * interoperable way with other types of LDAP servers. 071 * </BLOCKQUOTE> 072 */ 073@NotExtensible() 074@NotMutable() 075@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 076public class SearchRequestAccessLogMessage 077 extends OperationRequestAccessLogMessage 078{ 079 /** 080 * The serial version UID for this serializable class. 081 */ 082 private static final long serialVersionUID = -6751258649156129642L; 083 084 085 086 // The typesOnly value for the search request. 087 @Nullable private final Boolean typesOnly; 088 089 // The alias dereferencing policy for the search request. 090 @Nullable private final DereferencePolicy derefPolicy; 091 092 // The size limit for the search request. 093 @Nullable private final Integer sizeLimit; 094 095 // The time limit for the search request. 096 @Nullable private final Integer timeLimit; 097 098 // The list of requested attributes for the search request. 099 @Nullable private final List<String> requestedAttributes; 100 101 // The scope for the search request. 102 @Nullable private final SearchScope scope; 103 104 // The base DN for the search request. 105 @Nullable private final String baseDN; 106 107 // The string representation of the filter for the search request. 108 @Nullable private final String filter; 109 110 111 112 /** 113 * Creates a new search request access log message from the provided message 114 * string. 115 * 116 * @param s The string to be parsed as a search request access log message. 117 * 118 * @throws LogException If the provided string cannot be parsed as a valid 119 * log message. 120 */ 121 public SearchRequestAccessLogMessage(@NotNull final String s) 122 throws LogException 123 { 124 this(new LogMessage(s)); 125 } 126 127 128 129 /** 130 * Creates a new search request access log message from the provided log 131 * message. 132 * 133 * @param m The log message to be parsed as a search request access log 134 * message. 135 */ 136 public SearchRequestAccessLogMessage(@NotNull final LogMessage m) 137 { 138 super(m); 139 140 baseDN = getNamedValue("base"); 141 filter = getNamedValue("filter"); 142 sizeLimit = getNamedValueAsInteger("sizeLimit"); 143 timeLimit = getNamedValueAsInteger("timeLimit"); 144 typesOnly = getNamedValueAsBoolean("typesOnly"); 145 146 SearchScope ss = null; 147 try 148 { 149 ss = SearchScope.definedValueOf(getNamedValueAsInteger("scope")); 150 } 151 catch (final Exception e) 152 { 153 Debug.debugException(e); 154 } 155 scope = ss; 156 157 DereferencePolicy deref = null; 158 final String derefStr = getNamedValue("deref"); 159 if (derefStr != null) 160 { 161 for (final DereferencePolicy p : DereferencePolicy.values()) 162 { 163 if (p.getName().equalsIgnoreCase(derefStr)) 164 { 165 deref = p; 166 break; 167 } 168 } 169 } 170 derefPolicy = deref; 171 172 final String attrStr = getNamedValue("attrs"); 173 if (attrStr == null) 174 { 175 requestedAttributes = null; 176 } 177 else if (attrStr.equals("ALL")) 178 { 179 requestedAttributes = Collections.emptyList(); 180 } 181 else 182 { 183 final LinkedList<String> attrs = new LinkedList<>(); 184 final StringTokenizer st = new StringTokenizer(attrStr, ",", false); 185 while (st.hasMoreTokens()) 186 { 187 attrs.add(st.nextToken()); 188 } 189 requestedAttributes = Collections.unmodifiableList(attrs); 190 } 191 } 192 193 194 195 /** 196 * Retrieves the base DN for the search request. 197 * 198 * @return The base DN for the search request, or {@code null} if it is not 199 * included in the log message. 200 */ 201 @Nullable() 202 public final String getBaseDN() 203 { 204 return baseDN; 205 } 206 207 208 209 /** 210 * Retrieves the scope for the search request. 211 * 212 * @return The scope for the search request, or {@code null} if it is not 213 * included in the log message. 214 */ 215 @Nullable() 216 public final SearchScope getScope() 217 { 218 return scope; 219 } 220 221 222 223 /** 224 * Retrieves a string representation of the filter for the search request. 225 * 226 * @return A string representation of the filter for the search request, or 227 * {@code null} if it is not included in the log message. 228 */ 229 @Nullable() 230 public final String getFilter() 231 { 232 return filter; 233 } 234 235 236 237 /** 238 * Retrieves a parsed representation of the filter for the search request. 239 * 240 * @return A parsed representation of the filter for the search request, or 241 * {@code null} if it is not included in the log message or the 242 * filter string cannot be parsed as a filter. 243 */ 244 @Nullable() 245 public final Filter getParsedFilter() 246 { 247 try 248 { 249 if (filter == null) 250 { 251 return null; 252 } 253 else 254 { 255 return Filter.create(filter); 256 } 257 } 258 catch (final Exception e) 259 { 260 Debug.debugException(e); 261 return null; 262 } 263 } 264 265 266 267 /** 268 * Retrieves the dereference policy for the search request. 269 * 270 * @return The dereference policy for the search request, or {@code null} if 271 * it is not included in the log message or the value cannot be 272 * parsed as a valid {@code DereferencePolicy} value. 273 */ 274 @Nullable() 275 public final DereferencePolicy getDereferencePolicy() 276 { 277 return derefPolicy; 278 } 279 280 281 282 /** 283 * Retrieves the size limit for the search request. 284 * 285 * @return The size limit for the search request, or {@code null} if it is 286 * not included in the log message or the value cannot be parsed as 287 * an integer. 288 */ 289 @Nullable() 290 public final Integer getSizeLimit() 291 { 292 return sizeLimit; 293 } 294 295 296 297 /** 298 * Retrieves the time limit for the search request. 299 * 300 * @return The time limit for the search request, or {@code null} if it is 301 * not included in the log message or the value cannot be parsed as 302 * an integer. 303 */ 304 @Nullable() 305 public final Integer getTimeLimit() 306 { 307 return timeLimit; 308 } 309 310 311 312 /** 313 * Retrieves the typesOnly value for the search request. 314 * 315 * @return {@code true} if only attribute type names should be included in 316 * entries that are returned, {@code false} if both attribute types 317 * and values should be returned, or {@code null} if is not included 318 * in the log message or cannot be parsed as a Boolean. 319 */ 320 @Nullable() 321 public final Boolean typesOnly() 322 { 323 return typesOnly; 324 } 325 326 327 328 /** 329 * Retrieves the list of requested attributes for the search request. 330 * 331 * @return The list of requested attributes for the search request, an empty 332 * list if the client did not explicitly request any attributes, or 333 * {@code null} if it is not included in the log message. 334 */ 335 @Nullable() 336 public final List<String> getRequestedAttributes() 337 { 338 return requestedAttributes; 339 } 340 341 342 343 /** 344 * {@inheritDoc} 345 */ 346 @Override() 347 @NotNull() 348 public final AccessLogOperationType getOperationType() 349 { 350 return AccessLogOperationType.SEARCH; 351 } 352}