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