001/*
002 * Copyright 2015-2021 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.exceptions.ScimException;
022
023import javax.ws.rs.client.Entity;
024import javax.ws.rs.client.Invocation;
025import javax.ws.rs.client.WebTarget;
026import javax.ws.rs.core.HttpHeaders;
027import javax.ws.rs.core.Response;
028
029/**
030 * A builder for SCIM replace requests.
031 */
032public final class ReplaceRequestBuilder<T extends ScimResource>
033    extends ResourceReturningRequestBuilder<ReplaceRequestBuilder<T>>
034{
035  private final T resource;
036  private String version;
037
038  /**
039   * Create a new replace request builder.
040   *
041   * @param target The WebTarget to PUT.
042   * @param resource The SCIM resource to replace.
043   */
044  public ReplaceRequestBuilder(final WebTarget target, final T resource)
045  {
046    super(target);
047    this.resource = resource;
048  }
049
050  /**
051   * Replace the resource only if the resource has not been modified from the
052   * resource provided.
053   *
054   * @return This builder.
055   */
056  public ReplaceRequestBuilder<T> ifMatch()
057  {
058    version = getResourceVersion(resource);
059    return this;
060  }
061
062  /**
063   * {@inheritDoc}
064   */
065  @Override
066  Invocation.Builder buildRequest()
067  {
068    Invocation.Builder request = super.buildRequest();
069    if(version != null)
070    {
071      request.header(HttpHeaders.IF_MATCH, version);
072    }
073    return request;
074  }
075
076  /**
077   * Invoke the SCIM replace request.
078   *
079   * @return The successfully replaced SCIM resource.
080   * @throws ScimException If an error occurred.
081   */
082  @SuppressWarnings("unchecked")
083  public T invoke() throws ScimException
084  {
085    return (T) invoke(resource.getClass());
086  }
087
088  /**
089   * Invoke the SCIM modify request.
090   *
091   * @param <C> The type of object to return.
092   * @param cls The Java class object used to determine the type to return.
093   * @return The successfully modified SCIM resource.
094   * @throws javax.ws.rs.ProcessingException If a JAX-RS runtime exception occurred.
095   * @throws javax.ws.rs.ProcessingException If a JAX-RS runtime exception occurred.
096   * @throws ScimException If the SCIM service provider responded with an error.
097   */
098  public <C> C invoke(final Class<C> cls) throws ScimException
099  {
100    Response response = buildRequest().put(
101        Entity.entity(resource, getContentType()));
102    try
103    {
104      if(response.getStatusInfo().getFamily() ==
105          Response.Status.Family.SUCCESSFUL)
106      {
107        return response.readEntity(cls);
108      }
109      else
110      {
111        throw toScimException(response);
112      }
113    }
114    finally
115    {
116      response.close();
117    }
118  }
119}