/*
 * Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.jersey.client;

import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;

import javax.ws.rs.ProcessingException;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.client.ResponseProcessingException;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.client.internal.routing.ClientResponseMediaTypeDeterminer;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.inject.Providers;
import org.glassfish.jersey.model.internal.RankedComparator;
import org.glassfish.jersey.process.internal.AbstractChainableStage;
import org.glassfish.jersey.process.internal.ChainableStage;

Client filtering stage factory.
Author:Marek Potociar
/** * Client filtering stage factory. * * @author Marek Potociar */
class ClientFilteringStages { private ClientFilteringStages() { // Prevents instantiation }
Create client request filtering stage using the injection manager. May return null.
Params:
  • injectionManager – injection manager to be used.
Returns:configured request filtering stage, or null in case there are no client request filters registered in the injection manager.
/** * Create client request filtering stage using the injection manager. May return {@code null}. * * @param injectionManager injection manager to be used. * @return configured request filtering stage, or {@code null} in case there are no * {@link ClientRequestFilter client request filters} registered in the injection manager. */
static ChainableStage<ClientRequest> createRequestFilteringStage(InjectionManager injectionManager) { RankedComparator<ClientRequestFilter> comparator = new RankedComparator<>(RankedComparator.Order.ASCENDING); Iterable<ClientRequestFilter> requestFilters = Providers.getAllProviders(injectionManager, ClientRequestFilter.class, comparator); return requestFilters.iterator().hasNext() ? new RequestFilteringStage(requestFilters) : null; }
Create client request filtering stage using the injection manager. May return null.
Params:
  • firstFilter – Non null client request filter to be executed in the client request filtering stage.
  • injectionManager – injection manager to be used.
Returns:configured request filtering stage, or null in case there are no client request filters registered in the injection manager and firstFilter is null.
/** * Create client request filtering stage using the injection manager. May return {@code null}. * * @param firstFilter Non null {@link ClientRequestFilter client request filter} to be executed * in the client request filtering stage. * @param injectionManager injection manager to be used. * @return configured request filtering stage, or {@code null} in case there are no * {@link ClientRequestFilter client request filters} registered in the injection manager * and {@code firstFilter} is null. */
static ChainableStage<ClientRequest> createRequestFilteringStage(ClientRequestFilter firstFilter, InjectionManager injectionManager) { RankedComparator<ClientRequestFilter> comparator = new RankedComparator<>(RankedComparator.Order.ASCENDING); Iterable<ClientRequestFilter> requestFilters = Providers.getAllProviders(injectionManager, ClientRequestFilter.class, comparator); if (firstFilter != null && !requestFilters.iterator().hasNext()) { return new RequestFilteringStage(Collections.singletonList(firstFilter)); } else if (firstFilter != null && requestFilters.iterator().hasNext()) { return new RequestFilteringStage(prependFilter(firstFilter, requestFilters)); } return null; }
Create client response filtering stage using the injection manager. May return null.
Params:
  • injectionManager – injection manager to be used.
Returns:configured response filtering stage, or null in case there are no client response filters registered in the injection manager.
/** * Create client response filtering stage using the injection manager. May return {@code null}. * * @param injectionManager injection manager to be used. * @return configured response filtering stage, or {@code null} in case there are no * {@link ClientResponseFilter client response filters} registered in the injection manager. */
static ChainableStage<ClientResponse> createResponseFilteringStage(InjectionManager injectionManager) { RankedComparator<ClientResponseFilter> comparator = new RankedComparator<>(RankedComparator.Order.DESCENDING); Iterable<ClientResponseFilter> responseFilters = Providers.getAllProviders(injectionManager, ClientResponseFilter.class, comparator); return responseFilters.iterator().hasNext() ? new ResponseFilterStage(responseFilters) : null; }
Prepend an filter to a given iterable.
Params:
  • filter – to be prepend.
  • filters – the iterable the given filter is to be prependto
Type parameters:
  • <T> – filter type
Returns:iterable with first item of prepended filter.
/** * Prepend an filter to a given iterable. * @param filter to be prepend. * @param filters the iterable the given filter is to be prependto * @param <T> filter type * @return iterable with first item of prepended filter. */
private static <T> Iterable<T> prependFilter(T filter, Iterable<T> filters) { return new Iterable<T>() { boolean wasInterceptorFilterNext = false; final Iterator<T> filterIterator = filters.iterator(); @Override public Iterator<T> iterator() { return new Iterator<T>() { @Override public boolean hasNext() { return !wasInterceptorFilterNext || filterIterator.hasNext(); } @Override public T next() { if (wasInterceptorFilterNext) { return filterIterator.next(); } else { wasInterceptorFilterNext = true; return filter; } } }; } }; } private static final class RequestFilteringStage extends AbstractChainableStage<ClientRequest> { private final Iterable<ClientRequestFilter> requestFilters; private RequestFilteringStage(final Iterable<ClientRequestFilter> requestFilters) { this.requestFilters = requestFilters; } @Override public Continuation<ClientRequest> apply(ClientRequest requestContext) { for (ClientRequestFilter filter : requestFilters) { try { filter.filter(requestContext); final Response abortResponse = requestContext.getAbortResponse(); if (abortResponse != null) { final ClientResponseMediaTypeDeterminer determiner = new ClientResponseMediaTypeDeterminer( requestContext.getWorkers()); determiner.setResponseMediaTypeIfNotSet(abortResponse, requestContext.getConfiguration()); throw new AbortException(new ClientResponse(requestContext, abortResponse)); } } catch (IOException ex) { throw new ProcessingException(ex); } } return Continuation.of(requestContext, getDefaultNext()); } } private static class ResponseFilterStage extends AbstractChainableStage<ClientResponse> { private final Iterable<ClientResponseFilter> filters; private ResponseFilterStage(Iterable<ClientResponseFilter> filters) { this.filters = filters; } @Override public Continuation<ClientResponse> apply(ClientResponse responseContext) { try { for (ClientResponseFilter filter : filters) { filter.filter(responseContext.getRequestContext(), responseContext); } } catch (IOException ex) { InboundJaxrsResponse response = new InboundJaxrsResponse(responseContext, null); throw new ResponseProcessingException(response, ex); } return Continuation.of(responseContext, getDefaultNext()); } } }