001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2006-2008 Sun Microsystems, Inc.
025 *      Portions Copyright 2013-2015 ForgeRock AS
026 */
027package org.opends.server.protocols.ldap;
028
029import java.io.IOException;
030import java.util.LinkedHashSet;
031import java.util.Set;
032
033import org.forgerock.opendj.io.ASN1Writer;
034import org.forgerock.opendj.ldap.ByteString;
035import org.forgerock.opendj.ldap.DereferenceAliasesPolicy;
036import org.forgerock.opendj.ldap.SearchScope;
037import org.forgerock.util.Utils;
038import org.opends.server.types.RawFilter;
039
040import static org.opends.server.protocols.ldap.LDAPConstants.*;
041import static org.opends.server.util.ServerConstants.*;
042
043/**
044 * This class defines the structures and methods for an LDAP search request
045 * protocol op, which is used to locate entries based on a set of criteria.
046 */
047public class SearchRequestProtocolOp
048       extends ProtocolOp
049{
050
051  /** The typesOnly flag for this search request. */
052  private boolean typesOnly;
053
054  /** The alias dereferencing policy for this search request. */
055  private DereferenceAliasesPolicy dereferencePolicy;
056
057  /** The base DN for this search request. */
058  private ByteString baseDN;
059
060  /** The size limit for this search request. */
061  private int sizeLimit;
062
063  /** The time limit for this search request. */
064  private int timeLimit;
065
066  /** The filter for this search request. */
067  private RawFilter filter;
068
069  /** The set of requested attributes for this search request. */
070  private Set<String> attributes;
071
072  /** The scope for this search request. */
073  private SearchScope scope;
074
075
076
077  /**
078   * Creates a new search request protocol op with the provided information.
079   *
080   * @param  baseDN             The base DN for this search request.
081   * @param  scope              The scope for this search request.
082   * @param  dereferencePolicy  The alias dereferencing policy for this search
083   *                            request.
084   * @param  sizeLimit          The size limit for this search request.
085   * @param  timeLimit          The time limit for this search request.
086   * @param  typesOnly          The typesOnly flag for this search request.
087   * @param  filter             The filter for this search request.
088   * @param  attributes         The set of requested attributes for this search
089   *                            request.
090   */
091  public SearchRequestProtocolOp(ByteString baseDN, SearchScope scope,
092                                 DereferenceAliasesPolicy dereferencePolicy,
093                                 int sizeLimit, int timeLimit,
094                                 boolean typesOnly, RawFilter filter,
095                                 Set<String> attributes)
096  {
097    this.baseDN            = baseDN;
098    this.scope             = scope;
099    this.dereferencePolicy = dereferencePolicy;
100    this.sizeLimit         = sizeLimit;
101    this.timeLimit         = timeLimit;
102    this.typesOnly         = typesOnly;
103    this.filter            = filter;
104
105    if (attributes == null)
106    {
107      this.attributes = new LinkedHashSet<>(0);
108    }
109    else
110    {
111      this.attributes = attributes;
112    }
113  }
114
115
116
117  /**
118   * Retrieves the base DN for this search request.
119   *
120   * @return  The base DN for this search request.
121   */
122  public ByteString getBaseDN()
123  {
124    return baseDN;
125  }
126
127
128  /**
129   * Retrieves the scope for this search request.
130   *
131   * @return  The scope for this search request.
132   */
133  public SearchScope getScope()
134  {
135    return scope;
136  }
137
138
139  /**
140   * Retrieves the alias dereferencing policy for this search request.
141   *
142   * @return  The alias dereferencing policy for this search request.
143   */
144  public DereferenceAliasesPolicy getDereferencePolicy()
145  {
146    return dereferencePolicy;
147  }
148
149
150
151  /**
152   * Retrieves the size limit for this search request.
153   *
154   * @return  The size limit for this search request.
155   */
156  public int getSizeLimit()
157  {
158    return sizeLimit;
159  }
160
161
162
163  /**
164   * Retrieves the time limit for this search request.
165   *
166   * @return  The time limit for this search request.
167   */
168  public int getTimeLimit()
169  {
170    return timeLimit;
171  }
172
173
174
175  /**
176   * Retrieves the value of the typesOnly flag for this search request.
177   *
178   * @return  The value of tye typesOnly flag for this search request.
179   */
180  public boolean getTypesOnly()
181  {
182    return typesOnly;
183  }
184
185
186
187  /**
188   * Retrieves the filter for this search request.
189   *
190   * @return  The filter for this search request.
191   */
192  public RawFilter getFilter()
193  {
194    return filter;
195  }
196
197
198
199  /**
200   * Retrieves the set of requested attributes for this search request.  The
201   * returned list may be modified by the caller.
202   *
203   * @return  The set of requested attributes for this search request.
204   */
205  public Set<String> getAttributes()
206  {
207    return attributes;
208  }
209
210  @Override
211  public byte getType()
212  {
213    return OP_TYPE_SEARCH_REQUEST;
214  }
215
216  @Override
217  public String getProtocolOpName()
218  {
219    return "Search Request";
220  }
221
222  @Override
223  public void write(ASN1Writer stream) throws IOException
224  {
225    stream.writeStartSequence(OP_TYPE_SEARCH_REQUEST);
226    stream.writeOctetString(baseDN);
227    stream.writeEnumerated(scope.intValue());
228    stream.writeEnumerated(dereferencePolicy.intValue());
229    stream.writeInteger(sizeLimit);
230    stream.writeInteger(timeLimit);
231    stream.writeBoolean(typesOnly);
232    filter.write(stream);
233
234    stream.writeStartSequence();
235    for(String attribute : attributes)
236    {
237      stream.writeOctetString(attribute);
238    }
239    stream.writeEndSequence();
240
241    stream.writeEndSequence();
242  }
243
244  @Override
245  public void toString(StringBuilder buffer)
246  {
247    buffer.append("SearchRequest(baseDN=").append(baseDN);
248    buffer.append(", scope=").append(scope);
249    buffer.append(", derefPolicy=").append(dereferencePolicy);
250    buffer.append(", sizeLimit=").append(sizeLimit);
251    buffer.append(", timeLimit=").append(timeLimit);
252    buffer.append(", typesOnly=").append(typesOnly);
253    buffer.append(", filter=");
254    filter.toString(buffer);
255    buffer.append(", attributes={");
256
257    if (attributes != null && ! attributes.isEmpty())
258    {
259      Utils.joinAsString(buffer, ", ", attributes);
260    }
261
262    buffer.append("})");
263  }
264
265  @Override
266  public void toString(StringBuilder buffer, int indent)
267  {
268    StringBuilder indentBuf = new StringBuilder(indent);
269    for (int i=0 ; i < indent; i++)
270    {
271      indentBuf.append(' ');
272    }
273
274    buffer.append(indentBuf).append("Search Request").append(EOL);
275    buffer.append(indentBuf).append("  Base DN:  ").append(baseDN).append(EOL);
276    buffer.append(indentBuf).append("  Scope:  ").append(scope).append(EOL);
277    buffer.append(indentBuf).append("  Dereference Policy:  ").append(dereferencePolicy).append(EOL);
278    buffer.append(indentBuf).append("  Size Limit:  ").append(sizeLimit).append(EOL);
279    buffer.append(indentBuf).append("  Time Limit:  ").append(timeLimit).append(EOL);
280    buffer.append(indentBuf).append("  Types Only:  ").append(typesOnly).append(EOL);
281
282    buffer.append(indentBuf);
283    buffer.append("  Filter:  ");
284    filter.toString(buffer);
285    buffer.append(EOL);
286
287    buffer.append(indentBuf).append("  Attributes:").append(EOL);
288
289    if (attributes != null)
290    {
291      for (String attribute : attributes)
292      {
293        buffer.append(indentBuf).append("    ").append(attribute).append(EOL);
294      }
295    }
296  }
297}