org.nutz.plugins.view.ResourceBundleViewResolver Maven / Gradle / Ivy
package org.nutz.plugins.view;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.lang.Files;
import org.nutz.lang.Strings;
import org.nutz.mvc.ActionInfo;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.NutConfig;
import org.nutz.mvc.View;
import org.nutz.mvc.ViewMaker2;
import org.nutz.mvc.view.AbstractPathView;
/**
* 接口 ViewMaker2的实现,用于从 IOC 容器配置文件中查找视图。
*
* @author denghuafeng([email protected])
*
*/
public class ResourceBundleViewResolver implements ViewMaker2 {
private static final String OBJ = "obj";
private static final String REQUEST = "request";
private static final String RESPONSE = "response";
private static final String SESSION = "session";
private static final String APPLICATION = "application";
private static final String CONFIG = "conf";
private static final String MULTI_VIEW_RESOVER = "multiViewResover";
private static final String VIEW_NAME = "viewName";
private static final String PATH = "path";
private static final String BASE_PATH = "basePath";
private static final String SERVLET_EXTENSION = "servletExtension";
private static final String SERVLET_EXTENSION_KEY = "servlet.extension";
private static final String TPL_DIR = "tplDir";
private static final String RESOURCE_DIR = "resource.dir";
private static final String RES_PATH = "resPath";
private static final String TPL_RES_PATH = "tplResPath";
private static final String WEB_INF = "WEB-INF/";
private LinkedHashMap resolvers = new LinkedHashMap();
private MultiViewResover multiViewResover;
private PropertiesProxy config;
private String appRoot;
private boolean inited;
@Override
public View make(Ioc ioc, String type, String value) {
if (!inited) {
synchronized (resolvers) {
if (!inited) {
config = ioc.get(PropertiesProxy.class, CONFIG);
multiViewResover = ioc.get(MultiViewResover.class,
MULTI_VIEW_RESOVER);
if (multiViewResover != null) {
resolvers = multiViewResover.getResolvers();
}
if (resolvers == null || resolvers.size() == 0) {
return null;
}
inited = true;
}
}
}
final AbstractTemplateViewResolver vr = resolvers.get(type);
if (vr == null)
return null;
if (Strings.isBlank(vr.getPrefix()) || Strings.isBlank(vr.getSuffix())) {
throw new NullPointerException(vr.getClass().getSimpleName()
+ " prefix or suffix is null");
}
if (!vr.isInited) {
synchronized (vr) {
if (!vr.isInited) {
vr.init(appRoot, Mvcs.getServletContext());
vr.setInited(true);
}
}
}
return new AbstractPathView(value) {
public void render(HttpServletRequest req,
HttpServletResponse resp, Object obj) throws Throwable {
Map sv = new HashMap();
sv.put(OBJ, obj);
sv.put(REQUEST, req);
sv.put(RESPONSE, resp);
sv.put(SESSION, Mvcs.getHttpSession());
sv.put(APPLICATION, Mvcs.getServletContext());
sv.put(VIEW_NAME, vr.getClass().getSimpleName());
if (Strings.isBlank(resp.getContentType())
&& !Strings.isBlank(vr.getContentType())) {//resp的contentType优先级高
resp.setContentType(vr.getContentType());//配置文件设置的contentType
}
String evalPath = evalPath(req, obj);
String tplDir = vr.getPrefix();// 模板路径
String ext = vr.getSuffix();// 模板文件扩展名
if (Strings.isBlank(tplDir)) {
tplDir = "";
}
if (evalPath != null && evalPath.contains("?")) { // 将参数部分分解出来
evalPath = evalPath.substring(0, evalPath.indexOf('?'));
}
if (Strings.isBlank(evalPath)) {
evalPath = Mvcs.getRequestPath(req);
evalPath = tplDir + (evalPath.startsWith("/") ? "" : "/")
+ Files.renameSuffix(evalPath, ext);
}
// 绝对路径 : 以 '/' 开头的路径不增加视图配置的模板路径
else if (evalPath.charAt(0) == '/') {
if (!evalPath.toLowerCase().endsWith(ext))
evalPath += ext;
}
// 包名形式的路径
else {
evalPath = tplDir + "/" + evalPath.replace('.', '/') + ext;
}
String resDir = config.get(RESOURCE_DIR);
if (Strings.isBlank(resDir)) {
resDir = "";
}
String path = req.getContextPath();
int serverPort = req.getServerPort();
String basePath = req.getScheme() + "://" + req.getServerName()
+ (serverPort != 80 ? ":" + serverPort : "") + path
+ "/";
sv.put(PATH, path);
sv.put(BASE_PATH, basePath);
sv.put(SERVLET_EXTENSION, config.get(SERVLET_EXTENSION_KEY));
sv.put(TPL_DIR, tplDir);
if (!resDir.startsWith("http")) {// 如果是http开头,说明是CDN静态地址
resDir = path + "/" + resDir;
}
sv.put(RES_PATH, resDir);// 资源路径
sv.put(TPL_RES_PATH,
resDir + tplDir.replace(WEB_INF, "") + "/");// 模板对应的资源路径
vr.render(req, resp, evalPath, sv);
}
};
}
@Override
public View make(NutConfig conf, ActionInfo ai, String type, String value) {
appRoot = conf.getAppRoot();
return make(conf.getIoc(), type, value);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy