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