package act.controller;
/*-
* #%L
* ACT Framework
* %%
* Copyright (C) 2014 - 2017 ActFramework
* %%
* 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.
* #L%
*/
import act.ResponseImplBase;
import org.osgl.$;
import org.osgl.exception.UnexpectedIOException;
import org.osgl.http.H;
import org.osgl.storage.ISObject;
import org.osgl.storage.impl.SObject;
import org.osgl.util.IO;
import java.io.*;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import static org.osgl.http.H.Format.HTML;
import static org.osgl.http.H.Format.JSON;
import static org.osgl.http.H.Format.TXT;
public class ResponseCache extends ResponseImplBase implements Serializable {
private Map<String, H.Cookie> cookies = new HashMap<>();
private Map<String, String> headers = new HashMap<>();
private Long len;
private H.Status status;
private String content;
private byte[] binary;
private transient H.Response realResponse;
public ResponseCache() {}
public ResponseCache(H.Response realResponse) {
this.realResponse = $.notNull(realResponse);
}
public void applyTo(ResponseImplBase response) {
for (H.Cookie cookie : cookies.values()) {
response.addCookie(cookie);
}
for (Map.Entry<String, String> entry : headers.entrySet()) {
response.header(entry.getKey(), entry.getValue());
}
if (null != contentType) {
response.contentType(contentType);
}
if (null != charset) {
response.characterEncoding(charset);
}
response.commitContentType();
if (null != len) {
response.contentLength(len);
}
if (null != locale) {
response.locale(locale);
}
if (null != status) {
response.status(status);
}
if (null != content) {
response.writeContent(content);
} else if (null != binary) {
response.writeBinary(SObject.of(binary));
}
}
@Override
public H.Response context(Object context) {
realResponse.context(context);
return this;
}
@Override
public Object context() {
return realResponse.context();
}
@Override
public boolean writerCreated() {
return realResponse.writerCreated();
}
@Override
public OutputStream outputStream() throws IllegalStateException, UnexpectedIOException {
return realResponse.outputStream();
}
@Override
public Writer writer() throws IllegalStateException, UnexpectedIOException {
return realResponse.writer();
}
@Override
public PrintWriter printWriter() {
Writer w = writer();
if (w instanceof PrintWriter) {
return (PrintWriter) w;
} else {
return new PrintWriter(w);
}
}
@Override
public H.Response contentType(String type) {
realResponse.contentType(type);
contentType = type;
return this;
}
@Override
public H.Response initContentType(String type) {
realResponse.initContentType(type);
if (null == contentType) {
contentType = type;
}
return this;
}
@Override
public H.Response contentDisposition(String filename, boolean inline) {
realResponse.contentDisposition(filename, inline);
// set through header call
return this;
}
@Override
public H.Response prepareDownload(String filename) {
realResponse.prepareDownload(filename);
// set through header call
return this;
}
@Override
public H.Response etag(String etag) {
realResponse.etag(etag);
// set through header call
return this;
}
@Override
public H.Response locale(Locale locale) {
realResponse.locale(locale);
this.locale = locale;
return this;
}
@Override
public H.Response sendError(int sc, String msg, Object... args) {
realResponse.sendError(sc, msg, args);
return this;
}
@Override
public H.Response status(H.Status s) {
realResponse.status(s);
this.status = s;
return this;
}
@Override
public H.Response addHeaderIfNotAdded(String name, String value) {
realResponse.addHeaderIfNotAdded(name, value);
if (!headers.containsKey(name)) {
headers.put(name, value);
}
return this;
}
@Override
public H.Response writeBinary(ISObject binary) {
this.binary = binary.asByteArray();
IO.copy(SObject.of(this.binary).asInputStream(), realResponse.outputStream(), false);
return this;
}
@Override
public H.Response writeContent(String s) {
realResponse.writeContent(s);
this.content = s;
return this;
}
@Override
public H.Response writeText(String content) {
return writeContent(content, TXT);
}
@Override
public H.Response writeHtml(String content) {
return writeContent(content, HTML);
}
@Override
public H.Response writeJSON(String content) {
return writeContent(content, JSON);
}
private H.Response writeContent(String content, H.Format contentType) {
contentType(contentType.contentType());
writeContent(content);
return this;
}
@Override
protected Class _impl() {
return getClass();
}
@Override
protected OutputStream createOutputStream() {
return null;
}
@Override
public String characterEncoding() {
return charset;
}
@Override
public ResponseImplBase characterEncoding(String encoding) {
realResponse.characterEncoding(encoding);
super.characterEncoding(encoding);
return this;
}
@Override
public H.Response contentLength(long len) {
realResponse.contentLength(len);
this.len = len;
return this;
}
@Override
protected void _setContentType(String type) {
this.contentType = type;
}
@Override
protected void _setLocale(Locale loc) {
this.locale = loc;
}
@Override
public Locale locale() {
return realResponse.locale();
}
@Override
public void addCookie(H.Cookie cookie) {
realResponse.addCookie(cookie);
cookies.put(cookie.name(), cookie);
}
@Override
public boolean containsHeader(String name) {
return realResponse.containsHeader(name);
}
@Override
public H.Response sendError(int sc, String msg) {
realResponse.sendError(sc, msg);
return this;
}
@Override
public H.Response sendError(int sc) {
realResponse.sendError(sc);
return this;
}
@Override
public H.Response sendRedirect(String location) {
realResponse.sendRedirect(location);
return this;
}
@Override
public H.Response header(String name, String value) {
realResponse.header(name, value);
return this;
}
@Override
public H.Response status(int sc) {
realResponse.status(sc);
this.status = H.Status.of(sc);
return this;
}
@Override
public H.Response addHeader(String name, String value) {
realResponse.addHeader(name, value);
headers.put(name, value);
return this;
}
@Override
public H.Response writeContent(ByteBuffer buffer) {
realResponse.writeContent(buffer);
// we don't cache the byte buffer
return this;
}
@Override
public void commit() {
realResponse.commit();
}
}