- 浏览: 6821 次
- 性别:
- 来自: 南京
最新评论
启动:
net.jforum.JForum.java是核心Servlet,启动方法:
对文件的加载大体都在这个类里:net.jforum.ConfigLoader,分析一下文件修改的监听:
文件修改监听器net.jforum.util.FileMonitor:
论坛启动:net.jforum.ForumStartup
net.jforum.JForum.java是核心Servlet,启动方法:
public class JForum extends JForumBaseServlet { public void init(ServletConfig config) throws ServletException{ //调用父类JForumBaseServlet的init方法初始化 super.init(config); super.startApplication(); //根据配置文件实例化DBConnection的具体类,并初始化数据源 // Start database isDatabaseUp = ForumStartup.startDatabase(); try { Connection conn = DBConnection.getImplementation().getConnection(); conn.setAutoCommit(!SystemGlobals.getBoolValue(ConfigKeys.DATABASE_USE_TRANSACTIONS)); //解决MYSQL的问题,确定MYSQL版本,根据版本调整具体使用的JFORUM的MYSQL数据库驱动 // Try to fix some MySQL problems MySQLVersionWorkarounder dw = new MySQLVersionWorkarounder(); dw.handleWorkarounds(conn); //每个线程一个JForumExecutionContext // Continues loading the forum JForumExecutionContext ex = JForumExecutionContext.get(); ex.setConnection(conn); JForumExecutionContext.set(ex); //初始化缓存 //将论坛目录,论坛,最多在线用户数,用户数量,最近注册用户等信息放到缓存中 // Init general forum stuff ForumStartup.startForumRepository(); RankingRepository.loadRanks(); SmiliesRepository.loadSmilies(); BanlistRepository.loadBanlist(); } catch (Throwable e) { e.printStackTrace(); throw new ForumStartupException("Error while starting jforum", e); } finally { //启动完毕释放资源 JForumExecutionContext.finish(); } } }
public class JForumBaseServlet extends HttpServlet { private static Logger logger = Logger.getLogger(JForumBaseServlet.class); protected boolean debug; protected void startApplication() { try { //加载通用的SQL语句 SystemGlobals.loadQueries(SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_GENERIC)); //加载对于某一种数据库的驱动(专属某一库的SQL)相同的key将覆盖通用SQL中的值(properties.put) SystemGlobals.loadQueries(SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_DRIVER)); //获取quartz配置文件名 String filename = SystemGlobals.getValue(ConfigKeys.QUARTZ_CONFIG); //根据quartz配置文件路径加载quartz配置 SystemGlobals.loadAdditionalDefaults(filename); //生成用户认证类(net.jforum.sso.LoginAuthenticator)放到全局map(SystemGlobals.objectProperties)中默认的实现类是:net.jforum.sso.DefaultLoginAuthenticator,不是SSO ConfigLoader.createLoginAuthenticator(); // 加载net.jforum.dao.DataAccessDriver并初始化,具体的实现类在系统安装时生成的jforum-custom.conf文件中 ConfigLoader.loadDaoImplementation(); //监听文件修改(见下面对FileMonitor.java的分析) ConfigLoader.listenForChanges(); //初始化SearchFacade,被代理给SearchManager具体实现类在SystemGlobals.properties中配置,默认实现是net.jforum.search.LuceneManager ConfigLoader.startSearchIndexer(); //调度发送邮件 ConfigLoader.startSummaryJob(); } catch (Exception e) { throw new ForumStartupException("Error while starting JForum", e); } } public void init(ServletConfig config) throws ServletException { super.init(config); try { String appPath = config.getServletContext().getRealPath(""); debug = "true".equals(config.getInitParameter("development")); //初始化LOG4J DOMConfigurator.configure(appPath + "/WEB-INF/log4j.xml"); logger.info("Starting JForum. Debug mode is " + debug); //加载配置文件,在从配置文件中取值时遇到${}格式的会被当作变量进行扩展,与许多脚本语言类似 ConfigLoader.startSystemglobals(appPath); //启动缓存引擎 ConfigLoader.startCacheEngine(); //配置freemarker引擎 // Configure the template engine Configuration templateCfg = new Configuration(); templateCfg.setTemplateUpdateDelay(2); templateCfg.setSetting("number_format", "#"); templateCfg.setSharedVariable("startupTime", new Long(new Date().getTime())); //配置freemarker模板的加载目录 // Create the default template loader String defaultPath = SystemGlobals.getApplicationPath() + "/templates"; FileTemplateLoader defaultLoader = new FileTemplateLoader(new File(defaultPath)); String extraTemplatePath = SystemGlobals.getValue(ConfigKeys.FREEMARKER_EXTRA_TEMPLATE_PATH); if (StringUtils.isNotBlank(extraTemplatePath)) { // An extra template path is configured, we need a MultiTemplateLoader FileTemplateLoader extraLoader = new FileTemplateLoader(new File(extraTemplatePath)); TemplateLoader[] loaders = new TemplateLoader[] { extraLoader, defaultLoader }; MultiTemplateLoader multiLoader = new MultiTemplateLoader(loaders); templateCfg.setTemplateLoader(multiLoader); } else { // An extra template path is not configured, we only need the default loader templateCfg.setTemplateLoader(defaultLoader); } ModulesRepository.init(SystemGlobals.getValue(ConfigKeys.CONFIG_DIR)); this.loadConfigStuff(); if (!this.debug) { templateCfg.setTemplateUpdateDelay(3600); } //将模板的配置放到net.jforum.JForumExecutionContext JForumExecutionContext.setTemplateConfig(templateCfg); } catch (Exception e) { throw new ForumStartupException("Error while starting JForum", e); } } protected void loadConfigStuff() { //加载urlPattern.properties文件 ConfigLoader.loadUrlPatterns(); //加载i18n文件 I18n.load(); //加载templatesMapping.properties文件,供freemarker使用 Tpl.load(SystemGlobals.getValue(ConfigKeys.TEMPLATES_MAPPING)); // BB Code BBCodeRepository.setBBCollection(new BBCodeHandler().parse()); } }
对文件的加载大体都在这个类里:net.jforum.ConfigLoader,分析一下文件修改的监听:
public class ConfigLoader { public static void listenForChanges() { int fileChangesDelay = SystemGlobals.getIntValue(ConfigKeys.FILECHANGES_DELAY); if (fileChangesDelay > 0) { //这里用了单例和观察者模式,临听通用SQL语句配置文件的修改 // Queries FileMonitor.getInstance().addFileChangeListener(new QueriesFileListener(), SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_GENERIC), fileChangesDelay); //监听对某种数据库的SQL配置文件修改 FileMonitor.getInstance().addFileChangeListener(new QueriesFileListener(), SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_DRIVER), fileChangesDelay); //监听SystemGlobals.properties的修改 // System Properties FileMonitor.getInstance().addFileChangeListener(new SystemGlobalsListener(), SystemGlobals.getValue(ConfigKeys.DEFAULT_CONFIG), fileChangesDelay); ConfigLoader.listenInstallationConfig(); } } }
文件修改监听器net.jforum.util.FileMonitor:
public class FileMonitor { private static Logger logger = Logger.getLogger(FileMonitor.class); private static final FileMonitor instance = new FileMonitor(); private Timer timer; private Map timerEntries; private FileMonitor() { this.timerEntries = new HashMap(); this.timer = new Timer(true); } public static FileMonitor getInstance() { return instance; } public void addFileChangeListener(FileChangeListener listener, String filename, long period) { this.removeFileChangeListener(filename); logger.info("Watching " + filename); //通过JDK的TimerTask实现 FileMonitorTask task = new FileMonitorTask(listener, filename); this.timerEntries.put(filename, task); //定时调度 this.timer.schedule(task, period, period); } public void removeFileChangeListener(String filename) { FileMonitorTask task = (FileMonitorTask)this.timerEntries.remove(filename); if (task != null) { task.cancel(); } } //继承TimerTask private static class FileMonitorTask extends TimerTask { private FileChangeListener listener; private String filename; private File monitoredFile; private long lastModified; public FileMonitorTask(FileChangeListener listener, String filename) { this.listener = listener; this.filename = filename; this.monitoredFile = new File(filename); if (!this.monitoredFile.exists()) { return; } this.lastModified = this.monitoredFile.lastModified(); } public void run() { long latestChange = this.monitoredFile.lastModified(); //判断是否修改 if (this.lastModified != latestChange) { this.lastModified = latestChange; //修改触发事件 this.listener.fileChanged(this.filename); } } } }搜索:net.jforum.search.LuceneManager
public class LuceneManager implements SearchManager { private LuceneSearch search; private LuceneSettings settings; private LuceneIndexer indexer; /** * @see net.jforum.search.SearchManager#init() */ public void init() { try { //分词器根据配置文件中的配置实例化具体的分词器,配置文件中默认分词器:org.apache.lucene.analysis.standard.StandardAnalyzer Analyzer analyzer = (Analyzer)Class.forName(SystemGlobals.getValue( ConfigKeys.LUCENE_ANALYZER)).newInstance(); this.settings = new LuceneSettings(analyzer); //根据配置文件确定索引目录 this.settings.useFSDirectory(SystemGlobals.getValue(ConfigKeys.LUCENE_INDEX_WRITE_PATH)); this.removeLockFile(); this.indexer = new LuceneIndexer(this.settings); this.search = new LuceneSearch(this.settings, new LuceneContentCollector(this.settings)); this.indexer.watchNewDocuDocumentAdded(this.search); //将搜索配置放到全局对象中 SystemGlobals.setObjectValue(ConfigKeys.LUCENE_SETTINGS, this.settings); } catch (Exception e) { throw new ForumException(e); } } public LuceneSearch luceneSearch() { return this.search; } public LuceneIndexer luceneIndexer() { return this.indexer; } public void removeLockFile() { try { if (IndexReader.isLocked(this.settings.directory())) { IndexReader.unlock(this.settings.directory()); } } catch (IOException e) { throw new ForumException(e); } } /** * @see net.jforum.search.SearchManager#create(net.jforum.entities.Post) */ public void create(Post post) { this.indexer.create(post); } /** * @see net.jforum.search.SearchManager#update(net.jforum.entities.Post) */ public void update(Post post) { this.indexer.update(post); } /** * @see net.jforum.search.SearchManager#search(net.jforum.search.SearchArgs) */ public SearchResult search(SearchArgs args) { return this.search.search(args); } /** * @see net.jforum.search.SearchManager#delete(net.jforum.entities.Post) */ public void delete(Post p) { this.indexer.delete(p); } }
论坛启动:net.jforum.ForumStartup
public class ForumStartup { private static final Logger log = Logger.getLogger(ForumStartup.class); /** * Starts the database implementation * @return <code>true</code> if everthing were ok * @throws DatabaseException if something were wrong */ public static boolean startDatabase() { try { if (DBConnection.createInstance()) { DBConnection.getImplementation().init(); // Check if we're in fact up and running Connection conn = DBConnection.getImplementation().getConnection(); DBConnection.getImplementation().releaseConnection(conn); } } catch (Exception e) { throw new DatabaseException("Error while trying to start the database: " + e, e); } return true; } /** * Starts the cache control for forums and categories. * @throws RepositoryStartupException is something were wrong. */ public static void startForumRepository() { try { //使用单例 ForumDAO fm = DataAccessDriver.getInstance().newForumDAO(); CategoryDAO cm = DataAccessDriver.getInstance().newCategoryDAO(); ConfigDAO configModel = DataAccessDriver.getInstance().newConfigDAO(); //将论坛目录,论坛,最多在线用户数,用户数量,最近注册用户等信息放到缓存中 ForumRepository.start(fm, cm, configModel); } catch (Exception e) { log.error("Unable to bootstrap JForum repository.", e); throw new RepositoryStartupException("Error while trying to start ForumRepository: " + e, e); } } }
相关推荐
JForum3 jforum java 开源论坛 论坛
1、附件关系表JFORUM_ATTACH 2 2、附件详细信息表JFORUM_ATTACH_DESC 2 3、附件配置限定关系表JFORUM_ATTACH_QUOTA 2 4、封锁表JFORUM_BANLIST 2 5、标识表JFORUM_BANNER 3 6、书签表JFORUM_BOOKMARKS 3 7、...
jforum3.0所需要的jar包
JForum是著名的开源论坛,支持多达数十种的多国语言,其中包括简体中文。JForum功能强大,界面美观,加上代码结构清晰,而且采用的是BSD授权,不必担心不必要的版权纠纷。可以说JForum是论坛二次开发的绝佳选择。 ...
JForum - Java论坛系统 数据库表结构,如:附件关系表JFORUM_ATTACH,附件详细信息表JFORUM_ATTACH_DESC,用户分组表JFORUM_GROUPS等表结构说明,如帖子表JFORUM_POSTS说明: 名称 字段名 字段类型 字段说明 帖子...
Jforum论坛数据库架构Jforum论坛数据库架构
jforum漏洞利用源代码
jforum开源的论坛文档jforum开源的论坛文档jforum开源的论坛文档
jforum 完整源代码,从svn上 导出 没有任何修改
JForum 开源论坛系统的 数据库ER图,很详细。
1、包含jforum2.6.2的war包、源码包 2、war包可直接放在tomcat的webapps目录下 3、2.6.2版本里面自带汉化功能,在http://localhost:8080/jforum/install.jsp安装时,注意选择中文
JForum 是采用Java开发的功能强大且稳定的论坛系统。它提供了抽象的接口、高效的论坛引擎以及易于使用的管理界面,同时具有完全的权限控制、多语言支持(包括中文)、高性能、可自定义的用户接口、安全、支持多...
jforum的开发文档,以及源码解析 数据库 重要配置文件和包,缓存 权限控制 单点登录
jforum安装部署指南:修改对应的数据库文件JFORUM\WEB-INF\config\database下面。例如:mysql.properties修改其中的数据库信息
jforum3源代码数据库
用于配置中文jforum,里面包含各种语言的图片文件,将其中的zh_CN目录复制到jforum安装目录下的templates\default\images。就可以显示中文图片
对于我们已有的WEB应用中的用户,若该用户已经登陆,并通过 联结迁移到JForum页面时,JForum要能够识别该用户已经登陆(不需要二次登陆)才不会让用户感到别扭(对用户来说,就好像使用的是同一个系统似的)。...
Jforum二次开发成果 Jforum 二次开发 eclipse 给予JForum 2.1.8开发的一个小论坛。 增加了很多功能。(子论坛、主页、热门帖子、推荐帖子等)
jforum与ckeditor整合,替换自带的编辑器
JForum 开源代码,是很好的freeMaker学习素材。