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

org.refcodes.web.HttpServerRequest 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!
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.exception.UnmarshalException;
import org.refcodes.io.InputStreamStringBuilder;
import org.refcodes.textual.VerboseTextBuilder;

/**
 * Defines a {@link HttpServerRequest} being the request as consumed by the
 * server.
 */
public class HttpServerRequest extends AbstractHttpRequest implements HttpBodyAccessor, HttpInputStreamAccessor {

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

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

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

	/**
	 * Constructs a {@link HttpServerRequest} with all required attributes.
	 * 
	 * @param aHttpMethod The {@link HttpMethod} with which the request has been
	 *        sent.
	 * @param aUrl The {@link Url} from which to take the URL specific data.
	 * @param aHeaderFields The {@link RequestHeaderFields} sent by the request.
	 * @param aHttpInputStream The {@link InputStream} representing the
	 *        request's HTTP body.
	 * @param aMediaTypeFactoryLookup The lookup factory for retrieving the
	 *        required {@link MediaType} factories.
	 */
	public HttpServerRequest( HttpMethod aHttpMethod, Url aUrl, RequestHeaderFields aHeaderFields, InputStream aHttpInputStream, MediaTypeFactoryLookup aMediaTypeFactoryLookup ) {
		super( aHttpMethod, aUrl, aHeaderFields );
		_httpInputStream = aHttpInputStream;
		_mediaTypeFactoryLookup = aMediaTypeFactoryLookup;
	}

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

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

	/**
	 * This method's implementation supports the {@link HttpBodyMap} to
	 * unmarshal an HTTP Request-Body into an {@link HttpBodyMap} when providing
	 * the {@link HttpBodyMap} as request type.
	 *
	 * @param  the generic type
	 * @param aRequestType the request type
	 * 
	 * @return the request
	 * 
	 * @throws BadRequestException the bad request exception
	 */
	@SuppressWarnings("unchecked")
	public  REQ getRequest( Class aRequestType ) throws BadRequestException {
		if ( aRequestType.isAssignableFrom( InputStream.class ) ) {
			return (REQ) _httpInputStream;
		}
		final String theHttpBody = getHttpBody();
		if ( theHttpBody == null ) {
			return null;
		}
		if ( aRequestType.isAssignableFrom( String.class ) ) {
			return (REQ) theHttpBody;
		}

		Map theProperties = null;
		ContentType theContentType = getHeaderFields().getContentType();

		// Fallback from Accept-Types |-->
		if ( theContentType == null && getHeaderFields().getAcceptTypes() != null && getHeaderFields().getAcceptTypes().size() != 0 ) {
			for ( ContentType eContentType : getHeaderFields().getAcceptTypes() ) {
				if ( _mediaTypeFactoryLookup.hasMediaTypeFactory( eContentType.getMediaType() ) ) {
					theContentType = eContentType;
					break;
				}
			}
		}
		// Fallback from Accept-Types <--|

		MediaTypeFactory theFactory = null;
		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 = new HashMap<>();
				theProperties.put( MediaTypeParameter.CHARSET.getName(), theCharset );
			}
		}
		if ( theFactory == null ) {
			throw new BadRequestException( "No Media-Type factory found (added) for Media-Type <" + theContentType + "> (raw requested Media-Type is <" + getHeaderFields().get( HeaderField.CONTENT_TYPE ) + ">)" );
		}
		try {
			// HttpBodyMap support |-->
			if ( HttpBodyMap.class.isAssignableFrom( aRequestType ) ) {
				if ( theHttpBody.isEmpty() ) {
					return (REQ) new HttpBodyMap();
				}
				final Map theUnmarshaled = theFactory.toUnmarshaled( theHttpBody, Map.class, theProperties );
				return (REQ) new HttpBodyMap( theUnmarshaled );
			}
			// HttpBodyMap support <--|
			else {
				return theFactory.toUnmarshaled( theHttpBody, aRequestType, theProperties );
			}
		}
		catch ( UnmarshalException e ) {
			throw new BadRequestException( "Unable to unmarshal request body with Media-Type <" + new VerboseTextBuilder().toString( theFactory.getMediaTypes() ) + "> from URL <" + getUrl().toHttpUrl() + "> with HTTP-Method <" + getHttpMethod() + "> and request body <" + getHttpBody() + ">.", e );
		}
	}

	/**
	 * {@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();
						_httpBody = new InputStreamStringBuilder().toString( _httpInputStream, theEncoding );
					}
					catch ( IOException e ) {
						_httpBody = e.getMessage();
					}
				}
			}
		}
		return _httpBody;
	}

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy