org.simpleframework.http.message.EntityConsumer Maven / Gradle / Ivy
/*
* EntityConsumer.java February 2007
*
* Copyright (C) 2001, Niall Gallagher
*
* 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 org.simpleframework.http.message;
import static org.simpleframework.http.core.ContainerEvent.BODY_FINISHED;
import static org.simpleframework.http.core.ContainerEvent.HEADER_FINISHED;
import static org.simpleframework.http.core.ContainerEvent.READ_BODY;
import static org.simpleframework.http.core.ContainerEvent.READ_HEADER;
import java.io.IOException;
import org.simpleframework.transport.Channel;
import org.simpleframework.transport.Cursor;
import org.simpleframework.transport.trace.Trace;
import org.simpleframework.util.buffer.Allocator;
/**
* The EntityConsumer
object is used to consume data
* from a cursor and build a request entity. Each constituent part of
* the entity is consumed from the pipeline and can be acquired from
* this consumer object. The Header
and Body
* can be used to extract the individual parts of the entity.
*
* @author Niall Gallagher
*/
public class EntityConsumer implements Consumer {
/**
* This is used to create a body consumer for the entity.
*/
protected ConsumerFactory factory;
/**
* This is used to consume the header for the request entity.
*/
protected RequestConsumer header;
/**
* This represents the header characters that consumed so far.
*/
protected CharSequence sequence;
/**
* This is used to consume the body for the request entity.
*/
protected BodyConsumer body;
/**
* This is used to determine if there a continue is expected.
*/
protected Expectation expect;
/**
* This is used to trace the progress of the request consumption.
*/
protected Trace trace;
/**
* Constructor for the EntityConsumer
object. This
* is used to build an entity from the constituent parts. Once
* all of the parts have been consumed they are available from
* the exposed methods of this consumed instance.
*
* @param allocator this is used to allocate the memory used
* @param channel this is the channel used to send a response
*/
public EntityConsumer(Allocator allocator, Channel channel) {
this.header = new RequestConsumer();
this.expect = new Expectation(channel);
this.factory = new ConsumerFactory(allocator, header);
this.sequence = header.getHeader();
this.trace = channel.getTrace();
}
/**
* This is used to acquire the body for this HTTP entity. This
* will return a body which can be used to read the content of
* the message, also if the request is multipart upload then all
* of the parts are provided as Attachment
objects.
* Each part can then be read as an individual message.
*
* @return the body provided by the HTTP request message
*/
public Body getBody() {
return body.getBody();
}
/**
* This provides the HTTP request header for the entity. This is
* always populated and provides the details sent by the client
* such as the target URI and the query if specified. Also this
* can be used to determine the method and protocol version used.
*
* @return the header provided by the HTTP request message
*/
public Header getHeader() {
return header;
}
/**
* This consumes the header and body from the cursor. The header
* is consumed first followed by the body if there is any. There
* is a body of there is a Content-Length or a Transfer-Encoding
* header present. If there is no body then a substitute body
* is given which has an empty input stream.
*
* @param cursor used to consumed the bytes for the entity
*/
public void consume(Cursor cursor) throws IOException {
while(cursor.isReady()) {
if(header.isFinished()) {
if(body == null) {
trace.trace(HEADER_FINISHED, sequence);
body = factory.getInstance();
}
trace.trace(READ_BODY);
body.consume(cursor);
if(body.isFinished()) {
trace.trace(BODY_FINISHED);
break;
}
} else {
trace.trace(READ_HEADER);
header.consume(cursor);
}
}
if(header.isFinished()) {
if(body == null) {
trace.trace(HEADER_FINISHED, sequence);
expect.execute(header);
body = factory.getInstance();
}
}
}
/**
* This is determined finished when the body has been consumed.
* If only the header has been consumed then the body will be
* created using the header information, the body is then read
* from the cursor, which may read nothing for an empty body.
*
* @return this returns true if the entity has been built
*/
public boolean isFinished() {
if(header.isFinished()) {
if(body == null) {
trace.trace(HEADER_FINISHED, sequence);
body = factory.getInstance();
}
return body.isFinished();
}
return false;
}
/**
* This is used to determine if the header has finished. Exposing
* this method ensures the entity consumer can be used to determine
* if the header for the entity can be consumed before fully
* processing the entity body of the request message.
*
* @return determines if the header has been fully consumed
*/
public boolean isHeaderFinished() {
return header.isFinished();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy