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 2012-2016 ForgeRock AS.
015 */
016package org.forgerock.opendj.rest2ldap;
017
018import java.util.List;
019import java.util.Set;
020
021import org.forgerock.json.JsonPointer;
022import org.forgerock.json.JsonValue;
023import org.forgerock.json.resource.PatchOperation;
024import org.forgerock.json.resource.ResourceException;
025import org.forgerock.opendj.ldap.Attribute;
026import org.forgerock.opendj.ldap.Connection;
027import org.forgerock.opendj.ldap.Entry;
028import org.forgerock.opendj.ldap.Filter;
029import org.forgerock.opendj.ldap.Modification;
030import org.forgerock.util.promise.Promise;
031
032/** An property mapper is responsible for converting JSON values to and from LDAP attributes. */
033public abstract class PropertyMapper {
034    /*
035     * This interface is an abstract class so that methods can be made package
036     * private until API is finalized.
037     */
038
039    PropertyMapper() {
040        // Nothing to do.
041    }
042
043    /**
044     * Maps a JSON value to one or more LDAP attributes, returning a promise
045     * once the transformation has completed. This method is invoked when a REST
046     * resource is created using a create request.
047     * <p>
048     * If the JSON value corresponding to this mapper is not present in the
049     * resource then this method will be invoked with a value of {@code null}.
050     * It is the responsibility of the mapper implementation to take appropriate
051     * action in this case, perhaps by substituting default LDAP values, or by
052     * returning a failed promise with an appropriate {@link ResourceException}.
053     *
054     * @param connection
055     *            The LDAP connection to use to perform the operation.
056     * @param resource The exact type of resource being created.
057     * @param path
058     *            The pointer from the root of the JSON resource to this
059     *            property mapper. This may be used when constructing error
060     *            messages.
061     * @param v
062     *            The JSON value to be converted to LDAP attributes, which may
063     *            be {@code null} indicating that the JSON value was not present
064     *            in the resource.
065     * @return A {@link Promise} containing the result of the operation.
066     */
067    abstract Promise<List<Attribute>, ResourceException> create(Connection connection, Resource resource,
068                                                                JsonPointer path, JsonValue v);
069
070    /**
071     * Adds the names of the LDAP attributes required by this property mapper
072     * to the provided set.
073     * <p>
074     * Implementations should only add the names of attributes found in the LDAP
075     * entry directly associated with the resource.
076     *
077     * @param path
078     *            The pointer from the root of the JSON resource to this
079     *            property mapper. This may be used when constructing error
080     *            messages.
081     * @param subPath
082     *            The targeted JSON field relative to this property mapper, or
083     *            root if all attributes associated with this mapper have been
084     *            targeted.
085     * @param ldapAttributes
086 *            The set into which the required LDAP attribute names should be
087     */
088    abstract void getLdapAttributes(JsonPointer path, JsonPointer subPath, Set<String> ldapAttributes);
089
090    /**
091     * Transforms the provided REST comparison filter parameters to an LDAP
092     * filter representation, returning a promise once the transformation has
093     * completed.
094     * <p>
095     * If an error occurred while constructing the LDAP filter, then a failed
096     * promise must be returned with an appropriate {@link ResourceException}
097     * indicating the problem which occurred.
098     *
099     * @param connection
100     *            The LDAP connection to use to perform the operation.
101     * @param resource The type of resource being queried.
102     * @param path
103     *            The pointer from the root of the JSON resource to this
104     *            property mapper. This may be used when constructing error
105     *            messages.
106     * @param subPath
107     *            The targeted JSON field relative to this property mapper, or
108     *            root if all attributes associated with this mapper have been
109     *            targeted.
110     * @param type
111     *            The type of REST comparison filter.
112     * @param operator
113     *            The name of the extended operator to use for the comparison,
114     *            or {@code null} if {@code type} is not
115     *            {@link FilterType#EXTENDED}.
116     * @param valueAssertion
117     *            The value assertion, or {@code null} if {@code type} is
118     *            {@link FilterType#PRESENT}.
119     * @return A {@link Promise} containing the result of the operation.
120     */
121    abstract Promise<Filter, ResourceException> getLdapFilter(Connection connection, Resource resource,
122                                                              JsonPointer path, JsonPointer subPath, FilterType type,
123                                                              String operator, Object valueAssertion);
124
125    /**
126     * Maps a JSON patch operation to one or more LDAP modifications, returning
127     * a promise once the transformation has completed. This method is invoked
128     * when a REST resource is modified using a patch request.
129     *
130     * @param connection
131     *            The LDAP connection to use to perform the operation.
132     * @param resource The exact type of resource being patched.
133     * @param path
134     *            The pointer from the root of the JSON resource to this
135     *            property mapper. This may be used when constructing error
136     *            messages.
137     * @param operation
138     *            The JSON patch operation to be converted to LDAP
139     *            modifications. The targeted JSON field will be relative to
140     *            this property mapper, or root if all attributes associated
141     *            with this mapper have been targeted.
142     * @return A {@link Promise} containing the result of the operation.
143     */
144    abstract Promise<List<Modification>, ResourceException> patch(Connection connection, Resource resource,
145                                                                  JsonPointer path, PatchOperation operation);
146
147    /**
148     * Maps one or more LDAP attributes to their JSON representation, returning
149     * a promise once the transformation has completed.
150     * <p>
151     * This method is invoked whenever an LDAP entry is converted to a REST
152     * resource, i.e. when responding to read, query, create, put, or patch
153     * requests.
154     * <p>
155     * If the LDAP attributes are not present in the entry, perhaps because they
156     * are optional, then implementations should return a successful promise
157     * with a result of {@code null}. If the LDAP attributes cannot be mapped
158     * for any other reason, perhaps because they are required but missing, or
159     * they contain unexpected content, then a failed promise must be returned
160     * with an appropriate exception indicating the problem which occurred.
161     *
162     * @param connection
163     *            The LDAP connection to use to perform the operation.
164     * @param resource The exact type of resource being read.
165     * @param path
166     *            The pointer from the root of the JSON resource to this
167     *            property mapper. This may be used when constructing error
168     *            messages.
169     * @param e
170     *            The LDAP entry to be converted to JSON.
171     * @return A {@link Promise} containing the result of the operation.
172     */
173    abstract Promise<JsonValue, ResourceException> read(Connection connection, Resource resource,
174                                                        JsonPointer path, Entry e);
175
176    /**
177     * Maps a JSON value to one or more LDAP modifications, returning a promise
178     * once the transformation has completed. This method is invoked when a REST
179     * resource is modified using an update request.
180     * <p>
181     * If the JSON value corresponding to this mapper is not present in the
182     * resource then this method will be invoked with a value of {@code null}.
183     * It is the responsibility of the mapper implementation to take appropriate
184     * action in this case, perhaps by substituting default LDAP values, or by
185     * returning a failed promise with an appropriate {@link ResourceException}.
186     *
187     * @param connection
188     *            The LDAP connection to use to perform the operation.
189     * @param resource The exact type of resource being updated.
190     * @param v
191     *            The JSON value to be converted to LDAP attributes, which may
192     *            be {@code null} indicating that the JSON value was not present
193     *            in the resource.
194     * @return A {@link Promise} containing the result of the operation.
195     */
196    abstract Promise<List<Modification>, ResourceException> update(Connection connection, Resource resource,
197                                                                   JsonPointer path, Entry e, JsonValue v);
198
199    // TODO: methods for obtaining schema information (e.g. name, description, type information).
200    // TODO: methods for creating sort controls.
201}