📄 pageparamsimpl.java
字号:
package com.onetsoft.fastjsp;
import com.onetsoft.fastjsp.util.ResourceResolver;
import com.onetsoft.fastjsp.util.StringUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
/**
* 页面参数
* 保存解析url取得的布局、页面名称和url参数
* <p/>
* pathinfo构成:hostname/moduleServletPath/[/layout][/[threads[-fid-1].html]]
* 注解:系统如何从url和布局参数定位模板位置呢?以下假设本FastJsp应用模块是"bbs":
* 1.类似url "http://host/bbs/md/threads/fid-1.html"代表 LayoutId:{"md"},标识将从 "布局模块模板目录\md\" 下寻找threads.jsp
* 2.上例可见 LayoutId 只有一个非空参量时,应注意该参量所代表的含义及其对应的模板位置
* 3.若参数解析的布局不存在,则使用缺省布局
* 4.在布局多余一个时url才会添加布局信息
* 5.单布局情况下,不提供 WelcomePageModule 支持,将自动跳转到配置的缺省布局。
* WelcomePageModule 只在多布局系统且 WelcomePageModule !=null 时提供服务,一般用于布局选择
* 6.在 WelcomePageModule==null 的情况下,无论布局多少都将自动跳转到缺省配置
* 7.!!特别重要说明!!!
* 访问页面无参数时,类似:"http://host/bbs/client/threads.html" 等同 "http://host/bbs/client/threads[/]" 目的是将"threads"也视作目录的一部分,
* 便于将来静态化时,页面目录便于管理。如 "....client/threads.html" or "....client/threads/" or "....client/threads/fid-1.html"
* <p/>
* 8.编码参数值
* 避免'-'符号与参数混淆,如:负值,字符串保护该字符
* 注:考虑性能问题,编码(/解码)只针对参数值
*
* @see LayoutId
* @see AbstractServicer#getWelcomePageModule()
* @see AbstractServicer#getLayoutModules()
* @see AbstractServicer#getDefaultLayoutModule()
* @since 3.1
*/
class PageParamsImpl implements PageParams {
PageModule layoutModule = null; //e.g:"md" 注:与 webModule 作用类似 ,但必须存在
String pageName = StringUtils.EMPTY; //不含任何路径的一个纯粹的文件名 e.g:"index","plugin/content/settings" NOTE:no suffix
Map parameterMap = null; //页面参数,注意:此参数直接用于 Data、request.getParameterMap 顺序:静态url参数 > url请求参数(form 或 附加请求参数)
private AbstractServicer servicer = null;
Class pageClass = null;
boolean defaultPageUsed = false; //标识页面类是否是缺省页面类
String pageClassStr = null; //要构造的页面类名称,但此类不一定存在。此变量仅用于配合页面类错误信息显示
LayoutId layoutId = null;
String pageUrlBase = null; //url base,e.g:"http://host-name:port/onet/forums/md-threads-fid-1.html"中的"/onet/forums/md/",若与缺省布局相同,则无"md"
private String templateContextBase = null; //当前页面所在 context 模板位置,用于获取根模板路径的静态资源 e.g:"/onet/onetforums"
private String templateContextPath = null; //当前页面所在 context 绝对位置,用于获取静态当前页面模板的静态资源 e.g:"http://host/onet/onetforums/skins/bbs/default/"
private String templateChild = null;
public PageParamsImpl(AbstractServicer servicer) {
this.servicer = servicer;
}
private final static String APP_SERVER_DEFAULT_WELCOME_PAGE = "/index.html";//"index.html" app server的缺省页面,可能不同!
/**
* @param path 即:pathInfo
*/
void init(String path) {
/* 解析页面各项参数*/
path = path == null ? StringUtils.EMPTY : path.trim();
if ((servicer.module.moduleServletPath == null && path.equals(APP_SERVER_DEFAULT_WELCOME_PAGE)) || (path.length() == 0 || (path.length() == 1 && path.charAt(0) == '/'))) {
PageModule welcomePage = servicer.getWelcomePageModule();
if (servicer.layoutModules.length > 1 && welcomePage != null)
layoutModule = welcomePage;
else
layoutModule = servicer.defaultPageModule;
pageName = servicer.module.welcomeFileName;
parameterMap = new HashMap(0);
} else {
int indexoOfDot = path.lastIndexOf('.');
if (indexoOfDot != -1)
path = path.substring(0, indexoOfDot); // "/bbs/threads/fid-1.html" -> "/bbs/threads/fid-1"
String para = null; //请求参数,如:"fid-1"
{
int index = path.indexOf('-');
if (index == -1) {
para = StringUtils.EMPTY;
} else {
int lastIndex = path.lastIndexOf('/');
if (index <= lastIndex) //参数以'-'连接,且只能放在最后
{
layoutModule = null;
return;
}
para = path.substring(lastIndex + 1); // "fid-1"
path = path.substring(0, lastIndex); // ""/bbs/threads
}
}
//解析布局、页面名称
int index = path.indexOf('/');
if (index == -1 || (path.length() == 1 && path.charAt(0) == '/')) { //e.g:"" or "/"
layoutModule = servicer.defaultPageModule;
} else {
//如:"/bbs" or ""/bbs/"
int secondIndex = path.indexOf('/', index + 1);
String fakeLay = null; //察看后续的url路径是 layout 还是 pageName
if (secondIndex == -1) {
fakeLay = path.substring(index + 1);
} else {
fakeLay = path.substring(index + 1, secondIndex);
}
layoutModule = findLayout(fakeLay);
if (layoutModule == null) { //布局不存在则使用缺省布局
layoutModule = servicer.defaultPageModule;
if (path.charAt(path.length() - 1) == '/')
pageName = path.substring(index + 1, path.length() - 1);
else
pageName = path.substring(index + 1);
} else {
if (secondIndex != -1 && path.length() - 1 > secondIndex)
if (path.charAt(path.length() - 1) == '/')
pageName = path.substring(secondIndex + 1, path.length() - 1);
else
pageName = path.substring(secondIndex + 1);
}
}
if (pageName.length() == 0)
pageName = servicer.module.welcomeFileName;
//解析请求参数
if (para.length() == 0) {
parameterMap = new HashMap(0);
} else {
/*解析参数信息 不能用StringUtils.split(s,char),其会忽略"zid-"空参数情况*/
int pos;
parameterMap = new HashMap(8);
String paraName = null;
index = -1;
while ((pos = para.indexOf('-', index + 1)) != -1) {
String s = para.substring(index + 1, pos);
if (paraName == null) {
paraName = s;
} else {
if (paraName.length() > 0)
parameterMap.put(paraName, decodeParaValue(s));
paraName = null;
}
index = pos;
}
if (index == -1) {
parameterMap.put(para, StringUtils.EMPTY);
} else {
if (paraName != null && paraName.length() > 0)
parameterMap.put(paraName, decodeParaValue(para.substring(index + 1)));
else
parameterMap.put(para.substring(index + 1), StringUtils.EMPTY);
}
}
}
if (layoutModule == null)
return;
/* 初始 layoutId */
layoutId = new LayoutId(layoutModule.getHrefChild());
/* pageUrlBase */
pageUrlBase = parsePageUrlBase();
/* 解析页面类 */
findPageClass();
}
private String decodeParaValue(String v) {
try {
return URLDecoder.decode(v, servicer.module.encoding);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return v;
}
private PageModule findLayout(String lay) {
if (lay.length() > 0)
for (int i = 0; i < servicer.layoutModules.length; i++) {
PageModule m = servicer.layoutModules[i];
if (m.getHrefChild().equals(lay))
return m;
}
return null;
}
/**
* 解析页面 url base
* 用于生成页面链接
* e.g:"/onet/forums/md/threads/fid-1.html"中的"/onet/forums/md/",若与缺省布局相同,则无"md/"
*
* @return
*/
private String parsePageUrlBase() {
StringBuffer buf = new StringBuffer(96).append(servicer.hostPath).append(servicer.servletContextPath);
buf.append('/');
if (servicer.layoutModules.length > 1 && layoutModule.getHrefChild().length() > 0)
buf.append(layoutModule.getHrefChild()).append('/');
return buf.toString();
}
// StringBuffer getUrlBase(String layout) {
StringBuffer getUrlBase(StringBuffer buf,PageModule layoutModule) {
buf.append(servicer.servletContextPath).append('/');
/*直接认为该布局存在与否,不可据此采用defaultLayout。因为从客户端链接到“管理页面首页”时,"layout"参数就为空*/
if (layoutModule != null && layoutModule.getHrefChild().length() > 0)
buf.append(layoutModule.getHrefChild()).append('/');
return buf;
}
public String getTemplateChild() {
if (templateChild == null) {
templateChild = servicer.getTemplateChild();
}
return templateChild;
}
public String getTemplateContextBase() {
if (templateContextBase == null) {
StringBuffer buf = new StringBuffer(48).append(servicer.contextPath);
if (servicer.module.pageTemplateBase.length() > 0)
buf.append('/').append(servicer.module.pageTemplateBase);
templateContextBase = buf.toString();
}
return templateContextBase;
}
public String getTemplateContextPath() {
if (templateContextPath == null) {
StringBuffer buf = new StringBuffer().append(servicer.hostPath).append(getTemplateContextBase());
if (servicer.layoutModules.length > 0 && layoutModule.getTemplateChild().length() > 0)
buf.append('/').append(layoutModule.getTemplateChild());
templateChild = getTemplateChild();
if (templateChild != null && templateChild.length() != 0)
buf.append('/').append(templateChild);
buf.append('/').toString();
templateContextPath = buf.toString();
}
return templateContextPath;
}
/**
* 取得JSP模板文件
* 位置定位:模板
*
* @param pageName
* @return 文件位置相对于 contextPath
*/
String getForwardingTemplateFile(String pageName) {
if (layoutModule == null)
return null;
StringBuffer buf = new StringBuffer(32);
if (servicer.module.pageTemplateBase.length() > 0)
buf.append('/').append(servicer.module.pageTemplateBase);
if (servicer.layoutModules.length > 0 && layoutModule.getTemplateChild().length() > 0)
buf.append('/').append(layoutModule.getTemplateChild());
templateChild = getTemplateChild();
if (templateChild != null && templateChild.length() != 0)
buf.append('/').append(templateChild);
buf.append('/').append(pageName).append(StringUtils.PAGE_EXT);
return buf.toString();
}
/**
* 解析包名:admin/index.jsp => [FastJsp.Page_Package_Name.]admin.index , index.jsp => [FastJsp.Page_Package_Name.]index
* 注:页面包名与页面名称大小写相同,但页面类首字符为大写
*
* @param
* @return
*/
private void findPageClass() {
//解析包名
StringBuffer buf = new StringBuffer(64).append(servicer.module.pagePackageBase);
if (servicer.layoutModules.length > 0 && layoutModule.getPackageChild().length() > 0)
buf.append('.').append(layoutModule.getPackageChild());
//支持类似插件的页面 "index" => "Index" , "plugin/content/settings" => "plugin.content.settings"
String pageName = this.pageName.replace('/', '.');
buf.append('.').append(pageName).append('.');
pageName = pageName.substring(pageName.lastIndexOf('.') + 1);
buf.append(Character.toUpperCase(pageName.charAt(0))).append(pageName.substring(1));
pageClassStr = buf.toString();
try {
pageClass = ResourceResolver.forName(pageClassStr);
} catch (ClassNotFoundException e) {
if (layoutModule != null) {
pageClass = layoutModule.getDefaultPage();
defaultPageUsed = true;
}
}
}
public PageModule getLayoutModule() {
return layoutModule;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -