org.glassfish.jersey.spi.ContentEncoder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jaxrs-ri Show documentation
Show all versions of jaxrs-ri Show documentation
A bundle project producing JAX-RS RI bundles. The primary artifact is an "all-in-one" OSGi-fied JAX-RS RI bundle
(jaxrs-ri.jar).
Attached to that are two compressed JAX-RS RI archives. The first archive (jaxrs-ri.zip) consists of binary RI bits and
contains the API jar (under "api" directory), RI libraries (under "lib" directory) as well as all external
RI dependencies (under "ext" directory). The secondary archive (jaxrs-ri-src.zip) contains buildable JAX-RS RI source
bundle and contains the API jar (under "api" directory), RI sources (under "src" directory) as well as all external
RI dependencies (under "ext" directory). The second archive also contains "build.xml" ANT script that builds the RI
sources. To build the JAX-RS RI simply unzip the archive, cd to the created jaxrs-ri directory and invoke "ant" from
the command line.
/*
* Copyright (c) 2012, 2020 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.spi;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import jakarta.ws.rs.Priorities;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.ext.ReaderInterceptor;
import jakarta.ws.rs.ext.ReaderInterceptorContext;
import jakarta.ws.rs.ext.WriterInterceptor;
import jakarta.ws.rs.ext.WriterInterceptorContext;
import jakarta.annotation.Priority;
/**
* Standard contract for plugging in content encoding support. Provides a standard way of implementing encoding
* {@link WriterInterceptor} and decoding {@link ReaderInterceptor}. Implementing this class ensures the encoding
* supported by the implementation will be considered during the content negotiation phase when deciding which encoding
* should be used based on the accepted encodings (and the associated quality parameters) in the request headers.
*
* @author Martin Matula
*/
@Priority(Priorities.ENTITY_CODER)
@Contract
public abstract class ContentEncoder implements ReaderInterceptor, WriterInterceptor {
private final Set supportedEncodings;
/**
* Initializes this encoder implementation with the list of supported content encodings.
*
* @param supportedEncodings Values of Content-Encoding header supported by this encoding provider.
*/
protected ContentEncoder(String... supportedEncodings) {
if (supportedEncodings.length == 0) {
throw new IllegalArgumentException();
}
this.supportedEncodings = Collections.unmodifiableSet(Arrays.stream(supportedEncodings).collect(Collectors.toSet()));
}
/**
* Returns values of Content-Encoding header supported by this encoder.
* @return Set of supported Content-Encoding values.
*/
public final Set getSupportedEncodings() {
return supportedEncodings;
}
/**
* Implementations of this method should take the encoded stream, wrap it and return a stream that can be used
* to read the decoded entity.
*
*
* @param contentEncoding Encoding to be used to decode the stream - guaranteed to be one of the supported encoding
* values.
* @param encodedStream Encoded input stream.
* @return Decoded entity stream.
* @throws java.io.IOException if an IO error arises.
*/
public abstract InputStream decode(String contentEncoding, InputStream encodedStream) throws IOException;
/**
* Implementations of this method should take the entity stream, wrap it and return a stream that is encoded
* using the specified encoding.
*
*
* @param contentEncoding Encoding to be used to encode the entity - guaranteed to be one of the supported encoding
* values.
* @param entityStream Entity stream to be encoded.
* @return Encoded stream.
* @throws java.io.IOException if an IO error arises.
*/
public abstract OutputStream encode(String contentEncoding, OutputStream entityStream) throws IOException;
@Override
public final Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
String contentEncoding = context.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING);
if (contentEncoding != null && getSupportedEncodings().contains(contentEncoding)) {
context.setInputStream(decode(contentEncoding, context.getInputStream()));
}
return context.proceed();
}
@Override
public final void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
// must remove Content-Length header since the encoded message will have a different length
String contentEncoding = (String) context.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING);
if (contentEncoding != null && getSupportedEncodings().contains(contentEncoding)) {
context.setOutputStream(encode(contentEncoding, context.getOutputStream()));
}
context.proceed();
}
}