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.Invocation; 027import jakarta.ws.rs.client.WebTarget; 028import jakarta.ws.rs.core.HttpHeaders; 029import jakarta.ws.rs.core.Response; 030 031/** 032 * A builder for SCIM retrieve requests. 033 */ 034public abstract class RetrieveRequestBuilder 035 <T extends RetrieveRequestBuilder<T>> 036 extends ResourceReturningRequestBuilder<T> 037{ 038 /** 039 * The version to match. 040 */ 041 @Nullable 042 protected String version; 043 044 /** 045 * Create a new RetrieveRequestBuilder. 046 * 047 * @param target The WebTarget to GET. 048 */ 049 private RetrieveRequestBuilder(@NotNull final WebTarget target) 050 { 051 super(target); 052 } 053 054 /** 055 * {@inheritDoc} 056 */ 057 @Override 058 @NotNull 059 Invocation.Builder buildRequest() 060 { 061 Invocation.Builder request = super.buildRequest(); 062 if(version != null) 063 { 064 request.header(HttpHeaders.IF_NONE_MATCH, version); 065 } 066 return request; 067 } 068 069 070 /** 071 * A builder for SCIM retrieve requests for where the returned resource POJO 072 * type will be the same as the original. 073 */ 074 public static final class Generic<T extends ScimResource> 075 extends RetrieveRequestBuilder<Generic<T>> 076 { 077 @NotNull 078 private final T resource; 079 080 /** 081 * Create a new generic retrieve request builder. 082 * 083 * @param target The WebTarget to GET. 084 * @param resource The SCIM resource to retrieve. 085 */ 086 public Generic(@NotNull final WebTarget target, @NotNull final T resource) 087 { 088 super(target); 089 this.resource = resource; 090 } 091 092 /** 093 * Retrieve the resource only if the resource has been modified from the 094 * resource provided. If the resource has not been modified, the provided 095 * resource will be returned by invoke. 096 * 097 * @return This builder. 098 */ 099 @NotNull 100 public Generic<T> ifNoneMatch() 101 { 102 version = getResourceVersion(resource); 103 return this; 104 } 105 106 /** 107 * Invoke the SCIM retrieve request. 108 * 109 * @return The successfully retrieved SCIM resource or the resource provided 110 * if the ifNoneMatch method was called and the resource has not 111 * been modified. 112 * @throws ScimException If an error occurred. 113 */ 114 @NotNull 115 @SuppressWarnings("unchecked") 116 public T invoke() throws ScimException 117 { 118 return (T) invoke(resource.getClass()); 119 } 120 121 /** 122 * Invoke the SCIM modify request. 123 * 124 * @param <C> The type of object to return. 125 * @param cls The Java class object used to determine the type to return. 126 * @return The successfully modified SCIM resource. 127 * @throws ProcessingException If a JAX-RS runtime exception occurred. 128 * @throws ScimException If the SCIM service provider responded with an error. 129 */ 130 @NotNull 131 public <C> C invoke(@NotNull final Class<C> cls) throws ScimException 132 { 133 Response response = buildRequest().get(); 134 try 135 { 136 if(response.getStatusInfo().getFamily() == 137 Response.Status.Family.SUCCESSFUL) 138 { 139 return response.readEntity(cls); 140 } 141 else 142 { 143 throw toScimException(response); 144 } 145 } 146 finally 147 { 148 response.close(); 149 } 150 } 151 } 152 153 154 /** 155 * A builder for SCIM retrieve requests for where the returned resource POJO 156 * type will be provided. 157 */ 158 public static final class Typed extends RetrieveRequestBuilder<Typed> 159 { 160 /** 161 * Create a new generic retrieve request builder. 162 * 163 * @param target The WebTarget to GET. 164 */ 165 public Typed(@NotNull final WebTarget target) 166 { 167 super(target); 168 } 169 170 /** 171 * Retrieve the resource only if the resource has been modified since the 172 * provided version. If the resource has not been modified, 173 * NotModifiedException will be thrown when calling invoke. 174 * 175 * @param version The version of the resource to compare. 176 * @return This builder. 177 */ 178 @NotNull 179 public Typed ifNoneMatch(@Nullable final String version) 180 { 181 this.version = version; 182 return this; 183 } 184 185 /** 186 * Invoke the SCIM retrieve request. 187 * 188 * @param <T> The type of object to return. 189 * @param cls The Java class object used to determine the type to return. 190 * @return The successfully retrieved SCIM resource. 191 * @throws ProcessingException If a JAX-RS runtime exception occurred. 192 * @throws ScimException If the SCIM service provider responded with an error. 193 */ 194 @NotNull 195 public <T> T invoke(@NotNull final Class<T> cls) throws ScimException 196 { 197 Response response = buildRequest().get(); 198 try 199 { 200 if(response.getStatusInfo().getFamily() == 201 Response.Status.Family.SUCCESSFUL) 202 { 203 return response.readEntity(cls); 204 } 205 else 206 { 207 throw toScimException(response); 208 } 209 } 210 finally 211 { 212 response.close(); 213 } 214 } 215 } 216}