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