/* * Copyright (c) 2013-2014 the original author or authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.werval.runtime.outcomes; import java.io.InputStream; import java.nio.charset.Charset; import io.werval.api.Config; import io.werval.api.http.ResponseHeader; import io.werval.api.mime.MimeTypes; import io.werval.api.outcomes.Outcome; import io.werval.api.outcomes.OutcomeBuilder; import io.werval.util.ByteArrayByteSource; import io.werval.util.ByteSource; import static io.werval.api.http.Headers.Names.CONTENT_TYPE; import static io.werval.api.mime.MimeTypesNames.APPLICATION_JSON; import static io.werval.api.mime.MimeTypesNames.APPLICATION_XML; import static io.werval.api.mime.MimeTypesNames.TEXT_HTML; import static io.werval.api.mime.MimeTypesNames.TEXT_PLAIN; import static io.werval.runtime.ConfigKeys.WERVAL_CHARACTER_ENCODING; import static io.werval.runtime.ConfigKeys.WERVAL_HTTP_CHUNKSIZE; import static io.werval.util.ByteSource.EMPTY_BYTES; /** * Outcome Builder instance. */ public class OutcomeBuilderInstance implements OutcomeBuilder { private final Charset defaultCharset; private final MimeTypes mimeTypes; private final ResponseHeader response; private Object body = EMPTY_BYTES; private long length = 0; private int chunkSize; /* package */ OutcomeBuilderInstance( Config config, MimeTypes mimeTypes, ResponseHeader response ) { this.defaultCharset = config.charset( WERVAL_CHARACTER_ENCODING ); this.mimeTypes = mimeTypes; this.response = response; this.chunkSize = config.intNumber( WERVAL_HTTP_CHUNKSIZE ); } @Override public OutcomeBuilder withHeader( String name, String value ) { response.headers().with( name, value ); return this; } @Override public OutcomeBuilder as( String contentType ) { response.headers().withSingle( CONTENT_TYPE, contentType ); return this; } @Override public OutcomeBuilder asTextual( String contentType ) { return as( mimeTypes.withCharsetOfTextual( contentType ) ); } @Override public OutcomeBuilder asTextual( String contentType, Charset charset ) { return as( mimeTypes.withCharset( contentType, charset ) ); } @Override public OutcomeBuilder asTextPlain() { return as( mimeTypes.withCharsetOfTextual( TEXT_PLAIN ) ); } @Override public OutcomeBuilder asTextPlain( Charset charset ) { return as( mimeTypes.withCharset( TEXT_PLAIN, charset ) ); } @Override public OutcomeBuilder asJson() { return as( mimeTypes.withCharsetOfTextual( APPLICATION_JSON ) ); } @Override public OutcomeBuilder asJson( Charset charset ) { return as( mimeTypes.withCharset( APPLICATION_JSON, charset ) ); } @Override public OutcomeBuilder asXml() { return as( mimeTypes.withCharsetOfTextual( APPLICATION_XML ) ); } @Override public OutcomeBuilder asXml( Charset charset ) { return as( mimeTypes.withCharset( APPLICATION_XML, charset ) ); } @Override public OutcomeBuilder asHtml() { return as( mimeTypes.withCharsetOfTextual( TEXT_HTML ) ); } @Override public OutcomeBuilder asHtml( Charset charset ) { return as( mimeTypes.withCharset( TEXT_HTML, charset ) ); } @Override public OutcomeBuilder withBody( byte[] bodyBytes ) { body = new ByteArrayByteSource( bodyBytes ); length = bodyBytes.length; return this; } @Override public OutcomeBuilder withBody( CharSequence bodyChars ) { return withBody( bodyChars, defaultCharset ); } @Override public OutcomeBuilder withBody( CharSequence bodyChars, Charset charset ) { byte[] bodyBytes = bodyChars.toString().getBytes( charset ); body = new ByteArrayByteSource( bodyBytes ); length = bodyBytes.length; return this; } @Override public OutcomeBuilder withBody( InputStream bodyInputStream ) { body = bodyInputStream; length = -1; return this; } @Override public OutcomeBuilder withBody( InputStream bodyInputStream, int overridenChunkSize ) { body = bodyInputStream; length = -1; chunkSize = overridenChunkSize; return this; } @Override public OutcomeBuilder withBody( InputStream bodyInputStream, long bodyLength ) { body = bodyInputStream; length = bodyLength; return this; } @Override public Outcome build() { if( body == null ) { return new SimpleOutcome( response ); } if( body instanceof ByteSource ) { ByteSource bodyByteSource = (ByteSource) body; return new SimpleOutcome( response ).withEntity( bodyByteSource ); } if( body instanceof InputStream ) { InputStream bodyInputStream = (InputStream) body; if( length != -1 ) { return new InputStreamOutcome( response, bodyInputStream, length ); } return new ChunkedInputOutcome( response, bodyInputStream, chunkSize ); } throw new UnsupportedOperationException( "Unsupported body type ( " + body.getClass() + " ) " + body ); } }