001/* 002 * Copyright 2015-2024 Ping Identity Corporation 003 * 004 * This program is free software; you can redistribute it and/or modify 005 * it under the terms of the GNU General Public License (GPLv2 only) 006 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 007 * as published by the Free Software Foundation. 008 * 009 * This program is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU General Public License for more details. 013 * 014 * You should have received a copy of the GNU General Public License 015 * along with this program; if not, see <http://www.gnu.org/licenses>. 016 */ 017 018package com.unboundid.scim2.client.requests; 019 020import com.unboundid.scim2.common.ScimResource; 021import com.unboundid.scim2.common.annotations.NotNull; 022import com.unboundid.scim2.common.annotations.Nullable; 023import com.unboundid.scim2.common.exceptions.ScimException; 024 025import jakarta.ws.rs.ProcessingException; 026import jakarta.ws.rs.client.Entity; 027import jakarta.ws.rs.client.Invocation; 028import jakarta.ws.rs.client.WebTarget; 029import jakarta.ws.rs.core.HttpHeaders; 030import jakarta.ws.rs.core.Response; 031 032/** 033 * A builder for SCIM replace requests. 034 */ 035public final class ReplaceRequestBuilder<T extends ScimResource> 036 extends ResourceReturningRequestBuilder<ReplaceRequestBuilder<T>> 037{ 038 @NotNull 039 private final T resource; 040 041 @Nullable 042 private String version; 043 044 /** 045 * Create a new replace request builder. 046 * 047 * @param target The WebTarget to PUT. 048 * @param resource The SCIM resource to replace. 049 */ 050 public ReplaceRequestBuilder(@NotNull final WebTarget target, 051 @NotNull final T resource) 052 { 053 super(target); 054 this.resource = resource; 055 } 056 057 /** 058 * Replace the resource only if the resource has not been modified from the 059 * resource provided. 060 * 061 * @return This builder. 062 */ 063 @NotNull 064 public ReplaceRequestBuilder<T> ifMatch() 065 { 066 version = getResourceVersion(resource); 067 return this; 068 } 069 070 /** 071 * {@inheritDoc} 072 */ 073 @Override 074 @NotNull 075 Invocation.Builder buildRequest() 076 { 077 Invocation.Builder request = super.buildRequest(); 078 if(version != null) 079 { 080 request.header(HttpHeaders.IF_MATCH, version); 081 } 082 return request; 083 } 084 085 /** 086 * Invoke the SCIM replace request. 087 * 088 * @return The successfully replaced SCIM resource. 089 * @throws ScimException If an error occurred. 090 */ 091 @NotNull 092 @SuppressWarnings("unchecked") 093 public T invoke() throws ScimException 094 { 095 return (T) invoke(resource.getClass()); 096 } 097 098 /** 099 * Invoke the SCIM modify request. 100 * 101 * @param <C> The type of object to return. 102 * @param cls The Java class object used to determine the type to return. 103 * @return The successfully modified SCIM resource. 104 * @throws ProcessingException If a JAX-RS runtime exception occurred. 105 * @throws ScimException If the SCIM service provider responded with an error. 106 */ 107 @NotNull 108 public <C> C invoke(@NotNull final Class<C> cls) throws ScimException 109 { 110 Response response = buildRequest().put( 111 Entity.entity(resource, getContentType())); 112 try 113 { 114 if(response.getStatusInfo().getFamily() == 115 Response.Status.Family.SUCCESSFUL) 116 { 117 return response.readEntity(cls); 118 } 119 else 120 { 121 throw toScimException(response); 122 } 123 } 124 finally 125 { 126 response.close(); 127 } 128 } 129}