⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pageparamsimpl.java

📁 欢迎使用 FastJsp 开发框架! 编译说明: * 若要生成Api Javadoc文档
💻 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 + -