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
010 * docs/licenses/cddl.txt
011 * or http://www.opensource.org/licenses/cddl1.php.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * docs/licenses/cddl.txt.  If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 *      Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 *      Copyright 2013-2021 Ping Identity Corporation
026 */
027
028package com.unboundid.directory.sdk.broker.types;
029
030import com.unboundid.util.NotExtensible;
031
032
033
034/**
035 * Represents a request to update a specific entry in a Store Adapter.
036 *
037 * The UnboundID SCIM 2 SDK can be used to parse a SCIM patch request:
038 * <BR><BR>
039 * <PRE>
040 *   final ObjectReader reader =
041 *     JsonUtils.getObjectReader().forType(PatchRequest.class);
042 *   final PatchRequest patch =
043 *     reader.readValue(request.getPatchRequest());
044 * </PRE>
045 * The easiest way to process the update request is to retrieve the entry and
046 * apply the patch in memory using the PatchOperation.apply method using the
047 * SCIM 2 SDK:
048 * <BR><BR>
049 * <PRE>
050 *   // Retrieve the current entry from the store
051 *   final GenericScimResource resourceToUpdate = read(...);
052 *
053 *   // Apply the patch request in memory
054 *   patchOp.apply(resourceToUpdate);
055 *
056 *   // Replace the entire entry in the store
057 *   replace(resourceToUpdate);
058 * </PRE>
059 * Alternatively, if the underlying store does not support replacing the entire
060 * entry or to avoid the initial retrieval required to apply the patch in
061 * memory, the individual patch operations may be mapped to update requests
062 * supported by the underlying store. SCIM 2 (RFC 7644) patch operations are
063 * quite complicated in that an operation's path and value may take many forms
064 * but accomplish the same result. To make implementation easier, the patch
065 * operations in this request have been normalized so that there is only one
066 * form to accomplish a particular result. The operations in this request will
067 * have one of the following forms depending on the operation type, whether the
068 * attribute type is complex, and whether it is multi-valued:
069 *
070 * <H2>Add Operation</H2>
071 * <TABLE BORDER="1" SUMMARY="Patch operation forms for add">
072 *   <TR>
073 *     <TH>
074 *       "op" field
075 *     </TH>
076 *     <TH>
077 *       "path" field
078 *     </TH>
079 *     <TH>
080 *       "value" field
081 *     </TH>
082 *     <TH>
083 *       Description
084 *     </TH>
085 *   </TR>
086 *   <TR>
087 *    <TD>add</TD>
088 *    <TD>attributeName</TD>
089 *    <TD>valueNode or objectNode</TD>
090 *    <TD>
091 *      <UL>
092 *        <LI>
093 *          If the attribute does not exist, the attribute and value are added
094 *          to the resource.
095 *        </LI>
096 *        <LI>
097 *          If the attribute exists in the resource, the existing value is
098 *          replaced. If the existing value and the "value" parameter are
099 *          objects containing sub-attributes, those that did not previously
100 *          exist are added or their value replaced if they already exist.
101 *          Sub-attributes that are not specified in the "value" parameter are
102 *          left unchanged.
103 *        </LI>
104 *      </UL>
105 *    </TD>
106 *   </TR>
107 *   <TR>
108 *    <TD>add</TD>
109 *    <TD>attributeName</TD>
110 *    <TD>[valueNodes] or [objectNodes]</TD>
111 *    <TD>
112 *      <UL>
113 *        <LI>
114 *          If the attribute does not exist, the attribute and values are added
115 *          to the resource.
116 *        </LI>
117 *        <LI>
118 *          If the attribute exists in the resource, the new values are added
119 *          to the existing values.
120 *        </LI>
121 *      </UL>
122 *    </TD>
123 *   </TR>
124 * </TABLE>
125 * <H2>Remove Operation</H2>
126 * <TABLE BORDER="1" SUMMARY="Patch operation forms for remove">
127 *   <TR>
128 *     <TH>
129 *       "op" field
130 *     </TH>
131 *     <TH>
132 *       "path" field
133 *     </TH>
134 *     <TH>
135 *       "value" field
136 *     </TH>
137 *     <TH>
138 *       Description
139 *     </TH>
140 *   </TR>
141 *   <TR>
142 *    <TD>remove</TD>
143 *    <TD>attributeName</TD>
144 *    <TD></TD>
145 *    <TD>
146 *      <UL>
147 *        <LI>
148 *          Remove the attribute and its associated value(s) from the resource.
149 *        </LI>
150 *      </UL>
151 *    </TD>
152 *   </TR>
153 *   <TR>
154 *    <TD>remove</TD>
155 *    <TD>attributeName.subAttributeName</TD>
156 *    <TD></TD>
157 *    <TD>
158 *      <UL>
159 *        <LI>
160 *          Remove the sub-attribute from the attribute's associated value(s).
161 *          If no other sub-attributes remain after removal of the
162 *          targeted sub-attribute, the attribute should be removed from the
163 *          resource.
164 *        </LI>
165 *      </UL>
166 *    </TD>
167 *   </TR>
168 *   <TR>
169 *    <TD>remove</TD>
170 *    <TD>attributeName[valueFilter]</TD>
171 *    <TD></TD>
172 *    <TD>
173 *      <UL>
174 *        <LI>
175 *          Remove only the value(s) of the multi-valued attribute that matches
176 *          the value filter. For simple multi-valued attributes, the value
177 *          filter will be on an implicit "value" sub-attribute
178 *          (ie. value eq 100). If no other values remain after removal of the
179 *          selected values, the attribute should be removed from the resource.
180 *        </LI>
181 *      </UL>
182 *    </TD>
183 *   </TR>
184 *   <TR>
185 *    <TD>remove</TD>
186 *    <TD>attributeName[valueFilter].subAttributeName</TD>
187 *    <TD></TD>
188 *    <TD>
189 *      <UL>
190 *        <LI>
191 *          Remove the sub-attribute from any values of the multi-valued complex
192 *          attribute that matches the value filter. If no other values remain
193 *          after removal of the selected values, the attribute should be
194 *          removed from the resource.
195 *        </LI>
196 *      </UL>
197 *    </TD>
198 *   </TR>
199 * </TABLE>
200 * <H2>Replace Operation</H2>
201 * <TABLE BORDER="1" SUMMARY="Patch operation forms for replace">
202 *   <TR>
203 *     <TH>
204 *       "op" field
205 *     </TH>
206 *     <TH>
207 *       "path" field
208 *     </TH>
209 *     <TH>
210 *       "value" field
211 *     </TH>
212 *     <TH>
213 *       Description
214 *     </TH>
215 *   </TR>
216 *   <TR>
217 *    <TD>replace</TD>
218 *    <TD>attributeName</TD>
219 *    <TD>valueNode or objectNode</TD>
220 *    <TD>
221 *      <UL>
222 *        <LI>
223 *          If the attribute does not exist, the attribute and value are added
224 *          to the resource. (Same as add operation)
225 *        </LI>
226 *        <LI>
227 *          If the attribute exists in the resource, the existing value is
228 *          replaced. If the existing value and the "value" parameter are
229 *          objects containing sub-attributes, those that did not previously
230 *          exist are added or their value replaced if they already exist.
231 *          Sub-attributes that are not specified in the "value" parameter are
232 *          left unchanged. (Same as add operation)
233 *        </LI>
234 *      </UL>
235 *    </TD>
236 *   </TR>
237 *   <TR>
238 *    <TD>replace</TD>
239 *    <TD>attributeName</TD>
240 *    <TD>[valueNodes] or [objectNodes]</TD>
241 *    <TD>
242 *      <UL>
243 *        <LI>
244 *          If the attribute does not exist, the attribute and values are added
245 *          to the resource.
246 *        </LI>
247 *        <LI>
248 *          If the attribute exists in the resource, existing values are
249 *          replaced by new values.
250 *        </LI>
251 *      </UL>
252 *    </TD>
253 *   </TR>
254 *   <TR>
255 *    <TD>replace</TD>
256 *    <TD>attributeName[comparisonFilter]</TD>
257 *    <TD>valueNode or objectNode</TD>
258 *    <TD>
259 *      <UL>
260 *        <LI>
261 *          Replace only the value(s) of the multi-valued attribute that matches
262 *          the value filter. For simple multi-valued attributes, the value
263 *          filter will be on an implicit "value" sub-attribute
264 *          (ie. value eq 100). If no other values remain after removal of the
265 *          selected values, the attribute should be removed from the resource.
266 *          If the matched value and the "value" parameter are
267 *          objects containing sub-attributes, those that did not previously
268 *          exist are added or their value replaced if they already exists.
269 *          Sub-attributes that are not specified in the "value" parameter are
270 *          left unchanged.
271 *        </LI>
272 *      </UL>
273 *    </TD>
274 * </TABLE>
275 */
276@NotExtensible
277public interface StoreUpdateRequest
278    extends StoreRequest
279{
280  /**
281   * Retrieve the filter which identifies the entry to be updated.
282   * The UnboundID scim2 SDK Filter class can be used to parse a SCIM filter.
283   *
284   * @return  The filter which identifies the entry to be updated.
285   */
286  String getSCIMFilter();
287
288  /**
289   * Retrieve the SCIM patch request specifying the modifications to be
290   * processed.
291   *
292   * @return  The SCIM patch request specifying the modifications to be
293   * processed.
294   */
295  String getPatchRequest();
296}