opencms 发布过程深入研究

引入:

比起创建Resource,发布过程要困难很多,我上周在support team时候曾经设想不通过调试器,光走读代码来明白其中的奥秘,后来因为堆栈太深而放弃了,现在有了调试器,终于把这些细节弄明白了,果然非常复杂。

细节分析:

在发布Resource时,它的入口是CmsPublishProject类的actionPublish()方法,发布过程复杂到变态,全包装在performDialogOperation()方法中:

/***@seeorg.opencms.workplace.CmsMultiDialog#performDialogOperation()*/protectedbooleanperformDialogOperation()throwsCmsException{CmsPublishListpublishList=getSettings().getPublishList();if(publishList==null){thrownewCmsException(Messages.get().container(org.opencms.db.Messages.ERR_GET_PUBLISH_LIST_PROJECT_1,getProjectname()));}OpenCms.getPublishManager().publishProject(getCms(),newCmsHtmlReport(getLocale(),getCms().getRequestContext().getSiteRoot()),publishList);//wait2seconds,maybeitfinishesfastOpenCms.getPublishManager().waitWhileRunning(1500);returntrue;}

宏观上看,它先获得workplace中所有资源的发布列表,因为本例中只有一个资源,所以调试的列表如下:

[publishofproject:ae97ff1d-7824-11e4-8c0e-28e347ffa92bpublishhistoryID:f5d6e16a-787e-11e4-8289-28e347ffa92bresources:[[org.opencms.file.CmsResource,path:/sites/default/charles_study/publish_test1,structureidea051006-787e-11e4-8289-28e347ffa92b,resourceid:ea051007-787e-11e4-8289-28e347ffa92b,typeid:1,folder:false,flags:0,project:ae97ff1d-7824-11e4-8c0e-28e347ffa92b,state:2,datecreated:SunNov3018:52:01CST2014,usercreated:c300ba5c-01e8-3727-b305-5dcc9ccae1ee,datelastmodified:SunNov3018:52:09CST2014,userlastmodified:c300ba5c-01e8-3727-b305-5dcc9ccae1ee,datereleased:ThuJan0108:00:00CST1970,dateexpired:SunAug1715:12:55CST292278994,datecontent:SunNov3018:52:01CST2014,size:0,siblingcount:1,version:1]]folders:[]deletedFolders:[]]

其次,它通过CmsPublishManager的publishProject()方法来做对于待发布列表的资源的发布工作。

CmsPublishManager会调用CmsSecurityManager的publishProject()方法,最终调用CmsDriverManager的publishObject()方法来做发布的全部工作。这就是我们要讨论的重点。

重点探讨1: 从CmsDriverManager的publishObject()方法来研究发布过程。

发布过程代码很多也很深,从宏观上看,它做了这么几件事情:

a. 检查父目录,这主要用于是否存在该资产的父目录还没被发布的情况。

b.发起一个CmsEvent类的发布前事件(beforePublishEvent),该事件中除包含上面的发布资源列表(publishList)外还包含projectId,dbContext和一个空的发布报告对象(CmsHtmlReport,用于存储发布失败的错误),该事件中的数据如下:

{publishList=[publishofproject:ae97ff1d-7824-11e4-8c0e-28e347ffa92bpublishhistoryID:c0488fed-7882-11e4-8289-28e347ffa92bresources:[[org.opencms.file.CmsResource,path:/sites/default/charles_study/publish_test4,structureidbb3dab29-7882-11e4-8289-28e347ffa92b,resourceid:bb3dab2a-7882-11e4-8289-28e347ffa92b,typeid:1,folder:false,flags:0,project:ae97ff1d-7824-11e4-8c0e-28e347ffa92b,state:2,datecreated:SunNov3019:19:21CST2014,usercreated:c300ba5c-01e8-3727-b305-5dcc9ccae1ee,datelastmodified:SunNov3019:19:24CST2014,userlastmodified:c300ba5c-01e8-3727-b305-5dcc9ccae1ee,datereleased:ThuJan0108:00:00CST1970,dateexpired:SunAug1715:12:55CST292278994,datecontent:SunNov3019:19:21CST2014,size:0,siblingcount:1,version:1]]folders:[]deletedFolders:[]],dbContext=org.opencms.db.CmsDbContext@14b787a,report=org.opencms.report.CmsHtmlReport@1d2b627,projectId=ae97ff1d-7824-11e4-8c0e-28e347ffa92b}

然后用CmsEventManager的fireCmsEvent(beforePublishEvent)方法来执行这次发布事件。

因为一个资源的发布会影响到opencms的其他组件的更新,所以这里使用“Observer”设计模式,它吧多个cms的其他组件加到CmsEventManager的监听器列表中,监听器有几百个,我就不一一列出了。

c.用发布锁CmsLock锁住所有发布列表中的资源。

d.调用CmsPublishEngine的enqueuePublishJob()方法来记录下发布的计划任务,并产生具体的发布报告。具体来说:

生活的最大悲剧不是失败,而是一个人已经习惯于失败。

opencms 发布过程深入研究

相关文章:

你感兴趣的文章:

标签云: