您的位置:首页 > 职场人生

对大龄程序员的五大误解

2010-04-11 21:55 204 查看
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) //用户注册

这几个都是我将来要改造的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: