/* * EntityConsumer.java February 2007 * * Copyright (C) 2001, Niall Gallagher <niallg@users.sf.net> * * 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 <code>EntityConsumer</code> 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 * <code>Header</code> and <code>Body</code> 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 <code>EntityConsumer</code> 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, this.header); this.sequence = this.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 * <code>Attachment</code> objects. Each part can then be read as an * individual message. * * @return the body provided by the HTTP request message */ public Body getBody() { return this.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 this.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 */ @Override public void consume(Cursor cursor) throws IOException { while (cursor.isReady()) { if (this.header.isFinished()) { if (this.body == null) { this.trace.trace(HEADER_FINISHED, this.sequence); this.body = this.factory.getInstance(); } this.trace.trace(READ_BODY); this.body.consume(cursor); if (this.body.isFinished()) { this.trace.trace(BODY_FINISHED); break; } } else { this.trace.trace(READ_HEADER); this.header.consume(cursor); } } if (this.header.isFinished()) { if (this.body == null) { this.trace.trace(HEADER_FINISHED, this.sequence); this.expect.execute(this.header); this.body = this.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 */ @Override public boolean isFinished() { if (this.header.isFinished()) { if (this.body == null) { this.trace.trace(HEADER_FINISHED, this.sequence); this.body = this.factory.getInstance(); } return this.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 this.header.isFinished(); } }