public class ByteArrayResponseBody extends InputStreamResponseBody {

    public ByteArrayResponseBody(byte[] content) {
        super(new ByteArrayInputStream(content));
    }
} public class InputStreamResponseBody extends ResponseBody {

    private final InputStream in;
    
    public InputStreamResponseBody(InputStream in) {
        this.in = in;
    }
    
    @Override
    public void send(Response resp, String contentType) {
        try {
            sendContent(resp, contentType);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void sendAndCommit(Response resp, String contentType) {
        try {
            OutputStream out = sendContent(resp, contentType);
            out.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private OutputStream sendContent(Response resp, String contentType) throws IOException {
        
        OutputStream out = resp.getOutputStream();
        addStandardHeaders(resp, contentType);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        out.flush();
        return out;
    }
    
    @Override
    public boolean hasContent() {
        try {
            return in != null && in.available() > 0;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
} public class InterpolatedResponseBody extends StringResponseBody {

    public InterpolatedResponseBody(String body, HttpRequest req) {
        super(ResponseBodyInterpolator.interpolate(body, req));
    }
} public class MarshalledResponseBody extends InputStreamResponseBody {

    public MarshalledResponseBody(Object entity, Marshaller marshaller) {
        
        super(marshaller.marshal(entity));
    }
} public abstract class ResponseBody {

    public abstract void send(Response resp, String contentType);
    
    public abstract void sendAndCommit(Response resp, String contentType);
    
    public abstract boolean hasContent();
    
    protected void addStandardHeaders(Response response, String responseContentType) {
        
        long time = System.currentTimeMillis();
        response.setValue("Content-Type", responseContentType);
        response.setValue("Server", "Fixd/1.0 (Simple 5.1.4)");
        response.setDate("Date", time);
        response.setDate("Last-Modified", time);
    }
} public class StringResponseBody extends ResponseBody {

    private final String body;
    
    public StringResponseBody(String body) {
        this.body = body;
    }
    
    public boolean hasContent() {
        return body != null && body.trim().length() > 0;
    }
    
    @Override
    public void send(Response response, String contentType) {
        try {
            printBody(response, contentType);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void sendAndCommit(Response response, String contentType) {
        try {
            PrintStream ps = printBody(response, contentType);
            ps.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    private PrintStream printBody(Response response, String contentType) throws IOException {
        
        PrintStream ps = response.getPrintStream();
        addStandardHeaders(response, contentType);
        ps.println(body);
        ps.flush();
        return ps;
    }
} public interface Marshaller {

    InputStream marshal(Object entity);
} public interface MarshallerProvider {

    /**
     * 
     * Returns the Marshaller for the given content-type,
     * or null if there is no Marshaller for the given
     * content-type.
     * 
     * @param contentType
     * @return the Marshaller for the given content-type, or
     *         null if there is no Marshaller for the given
     *         content-type
     */
    Marshaller getMarshaller(String contentType);
} public interface HttpRequest {

    String getPath();
    
    String getUndecodedPath();
    
    Set<String> getRequestParameterNames();
    
    String getRequestParameter(String name);
    
    String getPathParameter(String name);
    
    List<String> getHeaderNames();
    
    String getHeaderValue(String name);
    
    String getBody();
    
    InputStream getBodyAsStream() throws IOException;
    
    <T> T getBody(Class<T> type);
    
    long getContentLength();
    
    String getContentType();
    
    String getMethod();
    
    long getTime();
    
    String getQuery();
    
    int getMajor();
    
    int getMinor();
    
    String getTarget();
    
    /**
     * @return a session, if it exists, or null if it does not
     */
    Session getSession();
    
    Route getRoute();
} public interface HttpResponse {

    void setBody(InputStream in);
    
    void setBody(byte[] content);
    
    void setBody(String content);
    
    void setBody(Object entity);
    
    /**
     * The body content set using this method will
     * be run through the response body interpolater.
     * 
     * @param content the content to be interpolated 
     * using path, request, and session params
     */
    void setInterpolatedBody(String content);
    
    void setContentType(String contentType);
    
    void setStatusCode(int statusCode);
    
    void setCookie(String name, String value);
    
    void addHeader(String name, String value);
    
    void redirect(String location);
    
    void redirect(String location, int statusCode);
}
import java.io.InputStream;
import org.bigtesting.fixd.core.body.ByteArrayResponseBody;
import org.bigtesting.fixd.core.body.InputStreamResponseBody;
import org.bigtesting.fixd.core.body.InterpolatedResponseBody;
import org.bigtesting.fixd.core.body.MarshalledResponseBody;
import org.bigtesting.fixd.core.body.ResponseBody;
import org.bigtesting.fixd.core.body.StringResponseBody;
import org.bigtesting.fixd.marshalling.Marshaller;
import org.bigtesting.fixd.marshalling.MarshallerProvider;
import org.bigtesting.fixd.request.HttpRequest;
import org.bigtesting.fixd.response.HttpResponse;
import org.simpleframework.http.Cookie;
import org.simpleframework.http.Response;
import org.simpleframework.http.Status;
/*
 * Copyright (C) 2015 BigTesting.org
 *
 * 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.bigtesting.fixd.response.impl;



/**
 * 
 * @author Luis Antunes
 */
public class SimpleHttpResponse implements HttpResponse {

    private final HttpRequest request;
    
    private final Response response;
    
    private ResponseBody body;
    private Object entity;
    private String contentType;
    private int statusCode;
    
    public SimpleHttpResponse(HttpRequest req, Response response) {
        this.request = req;
        this.response = response;
    }
    
    public void setBody(InputStream in) {
        this.body = new InputStreamResponseBody(in);
    }

    public void setBody(byte[] content) {
        this.body = new ByteArrayResponseBody(content);
    }

    public void setBody(String content) {
        this.body = new StringResponseBody(content);
    }
    
    public void setBody(Object entity) {
        this.entity = entity;
    }

    public void setInterpolatedBody(String content) {
        this.body = new InterpolatedResponseBody(content, request);