All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.refcodes.web.HttpClientResponse Maven / Gradle / Ivy

Go to download

This artifact provides web (HTTP) related definitions and types being used by REFCODES.ORG web related functionality and artifacts.

The newest version!
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// /////////////////////////////////////////////////////////////////////////////
// This code is copyright (c) by Siegfried Steiner, Munich, Germany, distributed
// on an "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, and licen-
// sed under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// -----------------------------------------------------------------------------
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// -----------------------------------------------------------------------------
// Apache License, v2.0 ("http://www.apache.org/licenses/TEXT-2.0")
// -----------------------------------------------------------------------------
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////

package org.refcodes.web;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.refcodes.data.Encoding;
import org.refcodes.io.InputStreamStringBuilder;

/**
 * Defines a {@link HttpClientResponse} being the response as consumed by the
 * client.
 */
public class HttpClientResponse extends AbstractHttpResponse implements HttpBodyAccessor, HttpInputStreamAccessor, UrlAccessor {

	// /////////////////////////////////////////////////////////////////////////
	// VARIABLES:
	// /////////////////////////////////////////////////////////////////////////

	protected MediaTypeFactoryLookup _mediaTypeFactoryLookup;
	private Url _url = null;
	private String _httpBody = null;
	private InputStream _httpInputStream = null;

	// /////////////////////////////////////////////////////////////////////////
	// CONSTRUCTORS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * Constructs a {@link HttpClientResponse} with all available attributes.
	 *
	 * @param aUrl The URL from which the response originates.
	 * @param aHeaderFields The {@link ResponseHeaderFields} sent by the
	 *        response.
	 * @param aMediaTypeFactoryLookup The lookup factory for retrieving the
	 *        required {@link MediaType} factories.
	 */
	public HttpClientResponse( Url aUrl, ResponseHeaderFields aHeaderFields, MediaTypeFactoryLookup aMediaTypeFactoryLookup ) {
		this( aUrl, null, aHeaderFields, null, aMediaTypeFactoryLookup );
	}

	/**
	 * Constructs a {@link HttpClientResponse} with all required attributes.
	 * 
	 * @param aUrl The URL from which the response originates.
	 * @param aHttpStatusCode The {@link HttpStatusCode} of the response.
	 * @param aHeaderFields The {@link ResponseHeaderFields} sent by the
	 *        response.
	 * @param aHttpInputStream The {@link InputStream} representing the
	 *        request's HTTP body.
	 * @param aMediaTypeFactoryLookup The lookup factory for retrieving the
	 *        required {@link MediaType} factories.
	 */
	public HttpClientResponse( Url aUrl, HttpStatusCode aHttpStatusCode, ResponseHeaderFields aHeaderFields, InputStream aHttpInputStream, MediaTypeFactoryLookup aMediaTypeFactoryLookup ) {
		super( aHttpStatusCode, aHeaderFields != null ? aHeaderFields : new ResponseHeaderFields() );
		_mediaTypeFactoryLookup = aMediaTypeFactoryLookup;
		_httpInputStream = aHttpInputStream;
		_url = aUrl;
	}

	// /////////////////////////////////////////////////////////////////////////
	// METHODS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * Retrieves the {@link HttpBodyMap} representing the response body.
	 * 
	 * @return An instance of the {@link HttpBodyMap} representing the response.
	 * 
	 * @throws BadResponseException thrown when unmarshaling / deserializing an
	 *         object fails.
	 */
	public HttpBodyMap getResponse() throws BadResponseException {
		return getResponse( HttpBodyMap.class );
	}

	/**
	 * This method's implementation supports the {@link HttpBodyMap} to
	 * unmarshal an HTTP Response-Body into an {@link HttpBodyMap} when
	 * providing the {@link HttpBodyMap} as response type.
	 *
	 * @param  the generic type
	 * @param aResponseType the response type
	 * 
	 * @return the response
	 * 
	 * @throws BadResponseException the bad response exception
	 */
	@SuppressWarnings("unchecked")
	public  RES getResponse( Class aResponseType ) throws BadResponseException {
		if ( aResponseType.isAssignableFrom( InputStream.class ) ) {
			return (RES) _httpInputStream;
		}
		if ( aResponseType.isAssignableFrom( String.class ) ) {
			return (RES) getHttpBody();
		}

		MediaTypeFactory theFactory = null;
		final Map theProperties = new HashMap<>();
		final String theHttpBody = getHttpBody();
		if ( theHttpBody != null ) {
			final ContentType theContentType = getHeaderFields().getContentType();
			if ( theContentType == null ) {
				final MediaType[] theMediaTypes = _mediaTypeFactoryLookup.getFactoryMediaTypes();
				if ( theMediaTypes != null && theMediaTypes.length != 0 ) {
					theFactory = _mediaTypeFactoryLookup.toMediaTypeFactory( theMediaTypes[0] );
				}
			}
			else {
				theFactory = _mediaTypeFactoryLookup.toMediaTypeFactory( theContentType.getMediaType() );
				final String theCharset = theContentType.getCharsetParametrer();
				if ( theCharset != null ) {
					theProperties.put( MediaTypeParameter.CHARSET.getName(), theCharset );
				}
			}
			if ( theFactory == null ) {
				throw new BadResponseException( "No Media-Type factory found (added) for Media-Type <" + theContentType + "> (raw requested Media-Type is <" + getHeaderFields().get( HeaderField.CONTENT_TYPE ) + ">)" );
			}
			try {
				theProperties.put( MediaTypeParameter.BASE_URL.getName(), _url.toHttpUrl() );
				// HttpBodyMap support |-->
				if ( HttpBodyMap.class.isAssignableFrom( aResponseType ) ) {
					final Map theUnmarshaled = theFactory.toUnmarshaled( theHttpBody, HashMap.class, theProperties );
					return (RES) new HttpBodyMap( theUnmarshaled );
				}
				// HttpBodyMap support <--|
				else {
					return theFactory.toUnmarshaled( theHttpBody, aResponseType, theProperties );
				}
			}
			catch ( Exception e ) {
				throw new BadResponseException( "Unable to parse response body {" + getHttpBody() + "}.", e );
			}
		}
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public InputStream getHttpInputStream() {
		return _httpInputStream;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getHttpBody() {
		if ( _httpBody == null ) {
			synchronized ( this ) {
				if ( _httpBody == null ) {
					try {
						final ContentType theContentType = getHeaderFields().getContentType();
						final String theEncoding = theContentType != null && theContentType.getCharsetParametrer() != null ? theContentType.getCharsetParametrer() : Encoding.UTF_8.getCode();

						//	while ( theEncoding.startsWith( "\"" ) ) {
						//		theEncoding = theEncoding.substring( 1 );
						//	}
						//	while ( theEncoding.endsWith( "\"" ) ) {
						//		theEncoding = theEncoding.substring( 0, theEncoding.length() - 1 );
						//	}

						_httpBody = new InputStreamStringBuilder().toString( _httpInputStream, theEncoding );
					}
					catch ( IOException e ) {
						_httpBody = e.getMessage();
					}
				}
			}
		}
		return _httpBody;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Url getUrl() {
		return _url;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String toString() {
		return getClass().getName() + " [httpStatusCode=" + _httpStatusCode + "]";
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy