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}