package act.view;
/*-
* #%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.app.ActionContext;
import org.osgl.http.H;
import org.osgl.mvc.result.RenderBinary;
import org.osgl.mvc.result.RenderJSON;
import org.osgl.mvc.result.Result;
import org.osgl.storage.ISObject;
import org.osgl.util.C;
import org.osgl.util.E;
import org.osgl.util.S;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.osgl.http.H.Format.*;
/**
* Render a template with template path and arguments provided
* by {@link ActionContext}
*/
public class RenderAny extends Result {
public static final RenderAny INSTANCE = new RenderAny();
public RenderAny() {
super(H.Status.OK);
}
@Override
public void apply(H.Request req, H.Response resp) {
throw E.unsupport("RenderAny does not support " +
"apply to request and response. Please use apply(AppContext) instead");
}
// TODO: Allow plugin to support rendering pdf, xls or other binary types
public void apply(ActionContext context) {
H.Format fmt = context.accept();
if (fmt == UNKNOWN) {
H.Request req = context.req();
H.Method method = req.method();
String methodInfo = S.concat(method.name(), " method to ");
String acceptHeader = req.header(H.Header.Names.ACCEPT);
throw E.unsupport(S.concat(
"Unknown accept content type(",
acceptHeader,
"): ",
methodInfo,
req.url()));
}
Result result = null;
if (JSON == fmt) {
List<String> varNames = context.__appRenderArgNames();
Map<String, Object> map = new HashMap<>(context.renderArgs());
if (null != varNames && !varNames.isEmpty()) {
for (String name : varNames) {
map.put(name, context.renderArg(name));
}
}
result = new RenderJSON(map);
} else if (XML == fmt) {
List<String> varNames = context.__appRenderArgNames();
Map<String, Object> map = C.newMap();
if (null != varNames && !varNames.isEmpty()) {
for (String name : varNames) {
map.put(name, context.renderArg(name));
}
}
result = new FilteredRenderXML(map, null, context);
} else if (HTML == fmt || TXT == fmt || CSV == fmt) {
RenderTemplate.get(context.successStatus()).apply(context);
return;
} else if (PDF == fmt || XLS == fmt || XLSX == fmt || DOC == fmt || DOCX == fmt) {
List<String> varNames = context.__appRenderArgNames();
if (null != varNames && !varNames.isEmpty()) {
Object firstVar = context.renderArg(varNames.get(0));
String action = S.str(context.actionPath()).afterLast(".").toString();
if (firstVar instanceof File) {
File file = (File) firstVar;
result = new RenderBinary(file, action);
} else if (firstVar instanceof InputStream) {
InputStream is = (InputStream) firstVar;
result = new RenderBinary(is, action);
} else if (firstVar instanceof ISObject) {
ISObject sobj = (ISObject) firstVar;
result = new RenderBinary(sobj.asInputStream(), action);
}
if (null == result) {
throw E.unsupport("Unknown render arg type [%s] for binary response", firstVar.getClass());
}
} else {
throw E.unexpected("No render arg found for binary response");
}
}
if (null != result) {
result.status(context.successStatus()).apply(context.req(), context.resp());
} else {
throw E.unexpected("Unknown accept content type: %s", fmt.contentType());
}
}
public static RenderAny get() {
return INSTANCE;
}
public static void clearThreadLocals() {
RenderTemplate.renderArgsBag.remove();
}
}