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 2010 Sun Microsystems, Inc.
025 *      Portions copyright 2011-2014 ForgeRock AS
026 */
027
028package org.opends.server.protocols.internal;
029
030import org.forgerock.i18n.LocalizedIllegalArgumentException;
031import org.forgerock.opendj.ldap.SearchScope;
032import org.forgerock.util.Reject;
033import org.opends.server.types.DN;
034import org.opends.server.types.DirectoryException;
035import org.opends.server.types.SearchFilter;
036
037/**
038 * This class contains various methods for creating and manipulating requests.
039 * <p>
040 * All copy constructors of the form {@code copyOfXXXRequest} perform deep
041 * copies of their request parameter. More specifically, any controls,
042 * modifications, and attributes contained within the response will be
043 * duplicated.
044 * <p>
045 * Similarly, all unmodifiable views of request returned by methods of the form
046 * {@code unmodifiableXXXRequest} return deep unmodifiable views of their
047 * request parameter. More specifically, any controls, modifications, and
048 * attributes contained within the returned request will be unmodifiable.
049 *
050 * @see org.forgerock.opendj.ldap.requests.Requests
051 */
052public final class Requests {
053
054    // TODO: search request from LDAP URL.
055
056    // TODO: update request from persistent search result.
057
058    // TODO: synchronized requests?
059
060    /**
061     * Creates a new search request using the provided distinguished name,
062     * scope, and filter.
063     *
064     * @param name
065     *            The distinguished name of the base entry relative to which the
066     *            search is to be performed.
067     * @param scope
068     *            The scope of the search.
069     * @param filter
070     *            The filter that defines the conditions that must be fulfilled
071     *            in order for an entry to be returned.
072     * @param attributeDescriptions
073     *            The names of the attributes to be included with each entry.
074     * @return The new search request.
075     * @throws NullPointerException
076     *             If the {@code name}, {@code scope}, or {@code filter} were
077     *             {@code null}.
078     */
079    public static SearchRequest newSearchRequest(final DN name, final SearchScope scope,
080            final SearchFilter filter, final String... attributeDescriptions)
081            throws NullPointerException {
082        Reject.ifNull(name, scope, filter);
083        final SearchRequest request = new SearchRequest(name, scope, filter);
084        for (final String attributeDescription : attributeDescriptions) {
085            request.addAttribute(attributeDescription);
086        }
087        return request;
088    }
089
090    /**
091     * Creates a new search request using the provided distinguished name,
092     * scope, and filter, decoded using the default schema.
093     *
094     * @param name
095     *            The distinguished name of the base entry relative to which the
096     *            search is to be performed.
097     * @param scope
098     *            The scope of the search.
099     * @param filter
100     *            The filter that defines the conditions that must be fulfilled
101     *            in order for an entry to be returned.
102     * @param attributeDescriptions
103     *            The names of the attributes to be included with each entry.
104     * @return The new search request.
105     * @throws  DirectoryException
106     *             If a problem occurs while decoding the provided string as a
107     *             search filter.
108     * @throws LocalizedIllegalArgumentException
109     *             If {@code name} could not be decoded using the default
110     *             schema, or if {@code filter} is not a valid LDAP string
111     *             representation of a filter.
112     * @throws NullPointerException
113     *             If the {@code name}, {@code scope}, or {@code filter} were
114     *             {@code null}.
115     */
116    public static SearchRequest newSearchRequest(final String name, final SearchScope scope,
117            final String filter, final String... attributeDescriptions)
118            throws NullPointerException, LocalizedIllegalArgumentException, DirectoryException {
119        Reject.ifNull(name, scope, filter);
120        SearchFilter f = "(objectclass=*)".equals(filter.toLowerCase())
121            ? SearchFilter.objectClassPresent()
122            : SearchFilter.createFilterFromString(filter);
123        final SearchRequest request = new SearchRequest(DN.valueOf(name), scope, f);
124        for (final String attributeDescription : attributeDescriptions) {
125            request.addAttribute(attributeDescription);
126        }
127        return request;
128    }
129
130    /**
131     * Return a new search request object.
132     *
133     * @param name
134     *          the dn
135     * @param scope
136     *          the search scope
137     * @param filter
138     *          the search filter
139     * @return a new search request object
140     * @throws DirectoryException
141     *           if a problem occurs
142     * @see #newSearchRequest(DN, SearchScope, SearchFilter, String...)
143     */
144    public static SearchRequest newSearchRequest(final String name, final SearchScope scope, final String filter)
145            throws DirectoryException {
146        return newSearchRequest(DN.valueOf(name), scope, SearchFilter.createFilterFromString(filter));
147    }
148
149    /**
150     * Return a new search request object.
151     *
152     * @param name
153     *          the dn
154     * @param scope
155     *          the search scope
156     * @param filter
157     *          the search filter
158     * @return a new search request object
159     * @throws DirectoryException
160     *           if a problem occurs
161     * @see #newSearchRequest(DN, SearchScope, SearchFilter, String...)
162     */
163    public static SearchRequest newSearchRequest(final DN name, final SearchScope scope, final String filter)
164            throws DirectoryException {
165        return newSearchRequest(name, scope, SearchFilter.createFilterFromString(filter));
166    }
167
168    /**
169     * Return a new search request object.
170     *
171     * @param name
172     *          the dn
173     * @param scope
174     *          the search scope
175     * @return a new search request object
176     * @see #newSearchRequest(DN, SearchScope, SearchFilter, String...)
177     */
178    public static SearchRequest newSearchRequest(final DN name, final SearchScope scope) {
179        return newSearchRequest(name, scope, SearchFilter.objectClassPresent());
180    }
181
182    private Requests() {
183        // Prevent instantiation.
184    }
185}