Package org.restlet.engine.connector

Source Code of org.restlet.engine.connector.ClientInboundWay

/**
* Copyright 2005-2011 Noelios Technologies.
*
* The contents of this file are subject to the terms of one of the following
* open source licenses: LGPL 3.0 or LGPL 2.1 or CDDL 1.0 or EPL 1.0 (the
* "Licenses"). You can select the license that you prefer but you may not use
* this file except in compliance with one of these Licenses.
*
* You can obtain a copy of the LGPL 3.0 license at
* http://www.opensource.org/licenses/lgpl-3.0.html
*
* You can obtain a copy of the LGPL 2.1 license at
* http://www.opensource.org/licenses/lgpl-2.1.php
*
* You can obtain a copy of the CDDL 1.0 license at
* http://www.opensource.org/licenses/cddl1.php
*
* You can obtain a copy of the EPL 1.0 license at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royalty free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://www.noelios.com/products/restlet-engine
*
* Restlet is a registered trademark of Noelios Technologies.
*/

package org.restlet.engine.connector;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.util.logging.Level;

import org.restlet.Client;
import org.restlet.Message;
import org.restlet.Response;
import org.restlet.data.Parameter;
import org.restlet.data.Status;
import org.restlet.engine.Engine;
import org.restlet.engine.header.HeaderConstants;
import org.restlet.engine.header.HeaderUtils;
import org.restlet.engine.io.IoState;
import org.restlet.util.Series;

/**
* Client-side inbound way.
*
* @author Jerome Louvel
*/
public abstract class ClientInboundWay extends InboundWay {

    /**
     * Constructor.
     *
     * @param connection
     *            The parent connection.
     * @param bufferSize
     *            The byte buffer size.
     */
    public ClientInboundWay(Connection<?> connection, int bufferSize) {
        super(connection, bufferSize);
    }

    /**
     * Copies headers into a response.
     *
     * @param headers
     *            The headers to copy.
     * @param response
     *            The response to update.
     */
    protected void copyResponseTransportHeaders(Series<Parameter> headers,
            Response response) {
        HeaderUtils.copyResponseTransportHeaders(headers, response);
    }

    /**
     * Creates a response object for the given status.
     *
     * @param status
     *            The response status.
     * @return The new response object.
     */
    protected abstract Response createResponse(Status status);

    /**
     * Returns the status corresponding to a given status code.
     *
     * @param code
     *            The status code.
     * @return The status corresponding to a given status code.
     */
    protected Status createStatus(int code) {
        return Status.valueOf(code);
    }

    @Override
    public Message getActualMessage() {
        return getMessage();
    }

    @SuppressWarnings("unchecked")
    @Override
    public Connection<Client> getConnection() {
        return (Connection<Client>) super.getConnection();
    }

    @Override
    public ClientConnectionHelper getHelper() {
        return (ClientConnectionHelper) super.getHelper();
    }

    @Override
    public int getInterestOperations() {
        int result = 0;

        if (getConnection().getState() == ConnectionState.OPENING) {
            result = SelectionKey.OP_CONNECT;
        } else {
            result = super.getInterestOperations();
        }

        return result;
    }

    @Override
    public void onCompleted(boolean endDetected) {
        // Check if we need to close the connection
        if (endDetected || !getConnection().isPersistent()
                || HeaderUtils.isConnectionClose(getHeaders())) {
            getConnection().close(true);
        }

        super.onCompleted(endDetected);
    }

    @Override
    protected void onReceived() {
        // Update the response
        getMessage().setEntity(createEntity(getHeaders()));

        try {
            copyResponseTransportHeaders(getHeaders(), getMessage());
        } catch (Throwable t) {
            getLogger()
                    .log(Level.WARNING, "Error while parsing the headers", t);
        }

        // Put the headers in the response's attributes map
        if (getHeaders() != null) {
            getMessage().getAttributes().put(HeaderConstants.ATTRIBUTE_HEADERS,
                    getHeaders());
        }

        onReceived(getMessage());
    }

    @Override
    protected void onReceived(Response message) {
        // Add it to the helper queue
        getHelper().getInboundMessages().add(getMessage());

        if (getMessage().isEntityAvailable()) {
            // Let's wait for the entity to be consumed by the caller
            setIoState(IoState.IDLE);
        } else {
            // The response has been completely read
            onCompleted(false);
        }
    }

    @Override
    protected void readStartLine() throws IOException {
        String version = null;
        int statusCode = -1;
        String reasonPhrase = null;

        int i = 0;
        int start = 0;
        int size = getLineBuilder().length();
        char next;

        if (size == 0) {
            // Skip leading empty lines per HTTP specification
        } else {
            // Parse the protocol version
            for (i = start; (version == null) && (i < size); i++) {
                next = getLineBuilder().charAt(i);

                if (HeaderUtils.isSpace(next)) {
                    version = getLineBuilder().substring(start, i);
                    start = i + 1;
                }
            }

            // Parse the status code
            for (i = start; (statusCode == -1) && (i < size); i++) {
                next = getLineBuilder().charAt(i);

                if (HeaderUtils.isSpace(next)) {
                    try {
                        statusCode = Integer.parseInt(getLineBuilder()
                                .substring(start, i));
                    } catch (NumberFormatException e) {
                        throw new IOException(
                                "Unable to parse the status code. Non numeric value: "
                                        + getLineBuilder().substring(start, i)
                                                .toString());
                    }

                    start = i + 1;
                }
            }

            if (statusCode == -1) {
                throw new IOException(
                        "Unable to parse the status code. End of line reached too early.");
            }

            // Parse the reason phrase
            for (i = start; (reasonPhrase == null) && (i < size); i++) {
                next = getLineBuilder().charAt(i);
            }

            if (i == size) {
                reasonPhrase = getLineBuilder().substring(start, i);
                start = i + 1;
            }

            if (reasonPhrase == null) {
                throw new IOException(
                        "Unable to parse the reason phrase. End of line reached too early.");
            }

            // Prepare the response
            Status status = createStatus(statusCode);
            Response response = createResponse(status);

            // Update the response
            response.setStatus(status, reasonPhrase);
            response.getServerInfo().setAddress(
                    getConnection().getSocket().getLocalAddress().toString());
            response.getServerInfo().setAgent(Engine.VERSION_HEADER);
            response.getServerInfo().setPort(
                    getConnection().getSocket().getPort());

            // Set the current message object
            setMessage(response);
            setMessageState(MessageState.HEADERS);
            clearLineBuilder();
        }
    }

}
TOP

Related Classes of org.restlet.engine.connector.ClientInboundWay

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.