`

chx 学习jForum笔记八-ForumAction三,发现用户认证模块。

阅读更多

2010.12.9。接昨天

在net.jforum.view.forum.common/ForumCommon.java中


    public static void checkUnreadPosts(final Forum forum, final Map<Integer, Long> tracking , final long lastVisit )
    {
        final LastPostInfo lpi = forum.getLastPostInfo (); //取Forum中最后贴子信息
        if (lpi == null) {
            return;
        }
        final Integer topicId = Integer.valueOf(lpi.getTopicId());  //Forum中最后贴子的主题ID
        //tracking 来自 SessionFacade.getTopicsReadTime() 最后阅读时间
        if (tracking != null && tracking.containsKey(topicId)) {   //tracking中读过此主题的记录
            final long readTime = tracking.get(topicId).longValue();  //tracking中读主题的时间
            forum.setUnread(readTime > 0 && lpi.getPostTimeMillis() > readTime);  //主题变更时间晚于阅读时间
        }
        else {
            forum.setUnread(lpi.getPostTimeMillis() > lastVisit); //主题变更时间晚于登录时间
        }
    }

 

从上面这段字看来,基本上是设置FORUM的状态,如果FORUM中有会员未读的帖子,就将状态设为未读。

这里有三个问题。一是tracking从哪里来的,查了一下,从SessionFacade.getTopicsReadTime()获取,但这里面的值又是什么时候设置的?二是lastVisit从哪里来的,来自userSession.getLastVisit().getTime(); //最后登录时间,同样的,这里面的值是什么时候设置的?三是forum.getLastPostInfo ();

 

在net.jforum.entities/Forum.java中

 

    public LastPostInfo getLastPostInfo() {
        return this.lpi;
    }

仅仅是返回一个属性,查构造函数:

    public Forum(final Forum forum)
    {
        this.description = forum.getDescription();
        this.id = forum.getId();
        this.idCategories = forum.getCategoryId();
        this.lastPostId = forum.getLastPostId();
        this.moderated = forum.isModerated();
        this.name = forum.getName();
        this.order = forum.getOrder();
        this.totalPosts = forum.getTotalPosts();
        this.totalTopics = forum.getTotalTopics();
        this.unread = forum.isUnread();
        this.lpi = forum.getLastPostInfo();
    }
居然也是这句:getLastPostInfo(),难道购造时已经有forum的值了吗?哦,有个传入的forum值。

 

    public void setLastPostInfo(final LastPostInfo lpi) {
        this.lpi = lpi;
    }

 

再普通不过的写值。全项目查找这个setLastPostInfo,得到四个结果,在同一个文件中。net.jforum.repository/ForumRepository.java

 

    public static LastPostInfo getLastPostInfo(Forum forum)  //取指定forum的最后帖子信息
    {
        LastPostInfo lpi = forum.getLastPostInfo(); //取指定forum的最后帖子信息
        if (lpi == null || !forum.getLastPostInfo().hasInfo()) { //信息为空
            lpi = DataAccessDriver.getInstance().newForumDAO().getLastPostInfo (forum.getId()); //从数据表中取信息
            forum.setLastPostInfo(lpi); //设置forum的最后帖子信息
        }
        return lpi; //返回forum的最后帖子信息
    }

 

嗯,看来这个最正确了。从数据表中取信息的。

 

net.jforum.dao.generic/GenericForumDAO.java

 

    public LastPostInfo getLastPostInfo(final int forumId)
    {
        return this.getLastPostInfo (forumId, true);
    }

 

找到主体了:

 

    private LastPostInfo getLastPostInfo(final int forumId, boolean origTryFix)
    {
        boolean tryFix = origTryFix;   //是否尝试修复
        final LastPostInfo lpi = new LastPostInfo();
        PreparedStatement pstmt = null;
        ResultSet resultSet = null;
        try { //读取sql语句。并设置参数
            pstmt = JForumExecutionContext.getConnection()
                    .prepareStatement(SystemGlobals.getSql("ForumModel.lastPostInfo"));
            pstmt.setInt(1, forumId);
            resultSet = pstmt.executeQuery(); //执行sql语句
            if (resultSet.next()) {
                lpi.setUsername(resultSet.getString("username")); //取用户名
                lpi.setUserId(resultSet.getInt("user_id"));      //取用户id
                final SimpleDateFormat sdf = new SimpleDateFormat(SystemGlobals.getValue(ConfigKeys.DATE_TIME_FORMAT), Locale.getDefault());
                lpi.setPostDate(sdf.format(resultSet.getTimestamp("post_time"))); //取发贴显示日期
                lpi.setPostId(resultSet.getInt("post_id")); //取帖子ID
                lpi.setTopicId(resultSet.getInt("topic_id")); //取主题ID
                lpi.setPostTimeMillis(resultSet.getTimestamp("post_time").getTime()); //取发贴时间
                lpi.setTopicReplies(resultSet.getInt("topic_replies")); //取主题回复数
                lpi.setHasInfo(true); //设为有信息
                lpi.setTitle(resultSet.getString("topic_title")); //取主题标题。
                // Check if the topic is consistent
                TopicDAO topicDao = DataAccessDriver.getInstance().newTopicDAO();
                Topic topic = topicDao.selectById(lpi.getTopicId()); //从数据表中取主题内容
                if (topic.getId() == 0) { //未取到主题,尝试修复
                    // Hm, that's not good. Try to fix it
                    topicDao.fixFirstLastPostId(lpi.getTopicId()); ////修复主题的首贴ID与尾贴ID
                }
                tryFix = false; //设置标志为“正常”非修复的。
            }
            else if (tryFix) { //未取到最后贴子信息并且需要尝试修复
                resultSet.close();
                pstmt.close();
                int postId = this.getMaxPostId(forumId); //初始值取最大的贴子ID
                 //读取sql语句。并设置参数
                pstmt = JForumExecutionContext.getConnection().prepareStatement(
                        SystemGlobals.getSql("ForumModel.latestTopicIdForfix"));
                pstmt.setInt(1, forumId);
                resultSet = pstmt.executeQuery();
                if (resultSet.next()) {
                    int topicId;
                    topicId = resultSet.getInt("topic_id"); //取SQL执行返回值。
                    resultSet.close();
                    pstmt.close();
                    // Topic 更新数据表内容
                    pstmt = JForumExecutionContext.getConnection().prepareStatement(
                            SystemGlobals.getSql("ForumModel.fixLatestPostData"));
                    pstmt.setInt(1, postId);
                    pstmt.setInt(2, topicId);
                    pstmt.executeUpdate();
                    pstmt.close();
                    // Forum 更新数据表内容
                    pstmt = JForumExecutionContext.getConnection().prepareStatement(
                            SystemGlobals.getSql("ForumModel.fixForumLatestPostData"));
                    pstmt.setInt(1, postId);
                    pstmt.setInt(2, forumId);
                    pstmt.executeUpdate();
                }
            }
            //如果是修复的,返回修复后的结果,否则返回取到的值。
            return (tryFix ? this.getLastPostInfo (forumId, false) : lpi);
        }
        catch (SQLException e) {
            throw new DatabaseException(e);
        }
        finally {
            DbUtils.close(resultSet, pstmt);
        }
    }

至此,getLastPostInfo研究结束,SQL语句来自于"ForumModel.lastPostInfo",并且还具有自查修复功能。

 

下面查SessionFacade.getTopicsReadTime()和userSession.getLastVisit().getTime();

 

net.jforum/SessionFacade.java

 

    public static Map<Integer, Long> getTopicsReadTime()
    {   //取属性
        Map<Integer, Long> tracking = (Map<Integer, Long>)getAttribute (ConfigKeys.TOPICS_READ_TIME);
        if (tracking == null) { //如果未取到
            tracking = new HashMap<Integer, Long>();  //新建一个空的
            setAttribute (ConfigKeys.TOPICS_READ_TIME, tracking);   //设置属性
        }
        return tracking;
    }

 

好象是直接去操作SESSION了。对这个我是一窍不通的。

 

    public static Object getAttribute(final String name)
    {
        return JForumExecutionContext.getRequest().getSessionContext().getAttribute(name);
    }

 

    public static void setAttribute(final String name, final Object value)
    {
        JForumExecutionContext.getRequest().getSessionContext().setAttribute(name, value);
    }

 

看看是什么时候设置进去的,查"setAttribute(ConfigKeys.TOPICS_READ_TIME",找到了四处,一处是上面的设置空值,一处是setAttribute(ConfigKeys.TOPICS_READ_TIME_BY_FORUM,……),当然也不对,一处是跟MAIL有关的,先排除,剩下最后一处最象。

但是,怎么又是空值?

SessionFacade.setAttribute(ConfigKeys.TOPICS_READ_TIME, new HashMap<Integer, Long>());

回过来再看第二处那个“ConfigKeys.TOPICS_READ_TIME_BY_FORUM”的。似乎有点象。

 

在net.jforum.view.forum/ForumAction.java中

 

    public void readAll() // 将所有主题标记为已读
    {
        String forumId = this.request.getParameter("forum_id");  //取查询参数
        if (forumId != null) {
            Map<Integer, Long> tracking = SessionFacade.getTopicsReadTimeByForum(); //取session中的值
            if (tracking == null) { //未取到
                tracking = new HashMap<Integer, Long>(); //建空值
            }
            tracking.put(Integer.valueOf(forumId), Long.valueOf(System.currentTimeMillis()));  //设置forumID及当前时间
            SessionFacade.setAttribute(ConfigKeys.TOPICS_READ_TIME_BY_FORUM, tracking); //设置session
        }
        if (forumId != null) {
            JForumExecutionContext.setRedirect(this.makeRedirect("show")); //重定向到show
        }
        else { //重定向到list
            JForumExecutionContext.setRedirect(this.request.getContextPath() + "/forums/list"
                + SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION));
        }
    }

看来,session中保存的ConfigKeys.TOPICS_READ_TIME_BY_FORUM 是板块的ID及查看时间。似乎并不是ConfigKeys.TOPICS_READ_TIME。再根据“TOPICS_READ_TIME”查找全文,仍然没有新的内容。也许没有实现这个主题阅读时间的功能吧。

 

反正 if (tracking != null && tracking.containsKey(topicId)) {   //tracking中读过此主题的记录

        else {
            forum.setUnread(lpi.getPostTimeMillis() > lastVisit); //主题变更时间晚于登录时间
        }

现在再查lastVisit。userSession.getLastVisit().getTime();

来自于net.jforum.entities/UserSession.java

 

    public Date getLastVisit()
    {
        //return new GregorianCalendar(2007, 6, 28, 15, 15, 19).getTime();
        return this.lastVisit;
    }

 

    public void setLastVisit(final Date lastVisit)
    {
        this.lastVisit = lastVisit;
    }

 

    public void registerBasicInfo() //注册基本信息
    {
        this.setStartTime(new Date(System.currentTimeMillis()));
        this.setLastVisit(new Date(System.currentTimeMillis()));
        this.setUserId(SystemGlobals.getIntValue(ConfigKeys.ANONYMOUS_USER_ID));
        this.setUsername(I18n.getMessage("Guest"));
    }

除了注册基本信息中会同时设置一下最后登录时间外,应该还有其他地方设置这个值。

查"setLastVisit",嗯,挺多的。

net.jforum/ControllerUtils.java中

    protected void configureUserSession(final UserSession userSession, final User user)//SSO登入认证成功后的操作。

 

net.jforum.view.forum/UserAction.java中

    private void logNewRegisteredUserIn(final int userId, final User user) //用户注册
    public void validateLogin() //用记登录校验

好了,看来这个LastVisit也仅仅是最后登录时间,而非最后看贴时间。

小结:

至此,ForumAction中的  this.context.put("allCategories", ForumCommon.getAllCategoriesAndForums(true));//页面显示的所有分类和板块(检查有无未读的贴子) 这句话研究结束。

不仅返回所有有权查看的分类、板块,同时还返回板块是否有未读贴子的状态。

关于用户认证,在net.jforum/ControllerUtils.java中的protected void configureUserSession(final UserSession userSession, final User user)//SSO登入认证成功后的操作。

及net.jforum.view.forum/UserAction.java中的 public void validateLogin() //用记登录校验

另外,用户注册在private void logNewRegisteredUserIn(final int userId, final User user) //用户注册
这几个都是我将来要改造的。

分享到:
评论

相关推荐

    chx 学习jForum笔记十八 jForum与ms sqlserver

    《jForum与MS SQLServer整合学习笔记》 jForum是一款基于Java的开源论坛系统,它以其高度可定制性、灵活性和强大的功能深受开发者喜爱。在本文中,我们将深入探讨如何将jForum与Microsoft SQL Server(简称MS SQL...

    北大计算机系高级计算机系统结构课件chx14-arch08-mm1

    【北京大学计算机科学高级计算机系统结构课件chx14-arch08-mm1】主要探讨了计算机系统中的主存,特别是动态随机存取内存(DRAM)的延迟问题以及解决策略。这一讲义由北京大学计算机科学技术系和微处理器研究开发中心...

    北大计算机系高级计算机系统结构课件chx14-arch03-ilp1

    在本课件中,主要讨论了三种数据相关类型:真数据相关(Data dependences)、名字相关(Name dependences)以及控制相关(Control dependences)。 1. **真数据相关(Data Dependences)**:这种相关指的是指令i的...

    CHX-I防火墙官方教程-附带翻译终稿.pdf

    CHX-I防火墙官方教程-附带翻译终稿.pdf

    北大计算机系高级计算机系统结构课件chx14-arch07-MT1

    每个线程都需要维护自己的用户状态,包括程序计数器(PC)和通用寄存器(GPRs)。同时,每个线程也需要自己的系统状态,如虚拟内存页表基址寄存器和异常处理相关的状态。此外,上下文切换(context switch)成本、...

    HA-SoftEther-CHX虚拟专网

    HA-SoftEther-CHX虚拟专网HA-SoftEther-CHX虚拟专网HA-SoftEther-CHX虚拟专网HA-SoftEther-CHX虚拟专网

    北大计算机系高级计算机系统结构课件chx14-arch05-ilp1

    这篇内容主要介绍了现代指令级并行技术在计算机系统结构中的应用,特别是关于指令流水线的设计和优化。在第五讲中,讲师程旭探讨了如何通过更复杂的流水线和动态调度来挖掘指令级并行性,以提高处理器性能。...

    北大计算机系高级计算机系统结构课件chx14-arch06-vliw1

    点数较多,以下将详细解析相关知识点: **高级计算机系统结构** 这门课程涉及的是计算机系统的核心设计原理,包括微处理器、流水线技术、指令级并行性(ILP)以及超长指令字(VLIW)架构。课程的重点在于理解和优化...

    北大计算机系高级计算机系统结构课件chx14-arch09-multiproc1

    "高级计算机系统结构-多处理器系统" 本资源是北京大学计算机科学技术系计算机系统结构教研室高等计算机系统结构(第九讲)的课件,讲解多处理器系统的相关知识内容。 多处理器系统的发展 多处理器系统的发展可以...

    北大计算机系高级计算机系统结构课件chx14-arch04-Tomasulo1

    北京大学计算机系的高级计算机系统结构课程中,第四讲主要讨论了Tomasulo算法,这是一种用于实现处理器指令级并行的技术。在讲解中,提到了几个关键概念,包括指令状态、功能单元状态以及寄存器结果状态。...

    北大计算机系高级计算机系统结构课件chx14-arch02-cache1

    【计算机系统结构与高速缓存】 在现代计算机体系结构中,高速缓存(Cache)扮演着至关重要的角色,它的存在主要是为了缓解处理器(CPU)与主内存(DRAM)之间速度不匹配的问题。随着技术的发展,处理器的速度不断...

    CHX(x=0-4在Y-Al2O3(ll0D)表面吸附的密度泛函研究 (2007年)

    使用基于密度泛函理论(DFT)的Cast叩量子力学计算程序模块,对CHX(X=0-4)在Y-AI2O3(ll0D)表面吸附的位置,空间结构和能量进行了理论计算。计算结果表明.CHx=(x=0-3)与表面形成强的相互作用。CH3,CH2物种处于表面八面体...

    CHX-I防火墙官方教程-附带翻译借鉴.pdf

    CHX-I防火墙官方教程-附带翻译借鉴.pdf

    CHX TNF JNK之间的关系

    这一研究聚焦于理解CHX(环己亚胺)、TNFα以及JNK(c-Jun N端激酶)三者之间的复杂关系,以及它们如何共同作用于人类肝癌细胞的凋亡过程。 ### CHX(环己亚胺) 环己亚胺(Cycloheximide,CHX)是一种蛋白质合成...

    chx99个人主页源码_chx99.zip

    【标题】"chx99个人主页源码_chx99.zip" 提供的是一个名为 chx99 的个人主页的源代码。源码通常包含了网站设计、布局、功能实现等核心部分,对于开发者而言是了解网站工作原理、学习前端技术或者进行二次开发的重要...

    永宏 FBs-4DA/2DA 模拟量输出模块使用说明.pdf

    模块的数值输出缓存器(OR)中的内容可以直接设置,例如FBs-2DA模块的起始缓存器地址由+0开始,对于每个CHx通道的输出值都可以通过相应的缓存器来设置。 硬件说明部分则提供了模块的具体电气参数和物理尺寸信息。...

    chx2095中文 英文资料

    根据给定的文件信息,我们可以提炼出以下关于CHX2095的详细IT知识: ### CHX2095概述 **CHX2095**是一款由United Monolithic Semiconductors S.A.S.制造的频率倍增器集成电路(IC),其工作频率范围在7.5至30GHz...

    CHX Hyper eXpressor-开源

    通过深入研究`chx-0.0.2`中的文件,开发者可以全面了解CHX的工作方式,并将其应用于自己的Web开发项目中。同时,参与开源社区,与全球的开发者交流,共同推动CHX Hyper eXpressor 的发展,也是提升自身技能和影响力...

    [CMS程序]chx99个人主页源码_chx99(ASP.NET源码).rar

    总之,通过对【CMS程序]chx99个人主页源码_chx99(ASP.NET源码)的深入研究,我们可以学习到ASP.NET Web Forms的开发技术,数据绑定,用户认证,配置管理,以及前端交互等多个方面,这将对提升我们的ASP.NET开发技能...

Global site tag (gtag.js) - Google Analytics