Commit f465958d authored by Liang Ding's avatar Liang Ding

Merge pull request #325 from b3log/0.6.5

0.6.5
parents 5163832f 50a5336f
...@@ -5,6 +5,21 @@ ...@@ -5,6 +5,21 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head> </head>
<body> <body>
<h2>Release 0.6.5 - Nov 1, 2013</h2>
<ul>
<li><a href="https://github.com/b3log/b3log-solo/issues/282">282 找回密码问题</a>&nbsp;<span style='background: #fc2929 !important;color:#FFFFFF !important;padding: 1px 4px;'>bug</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/283">283 社区同步评论</a>&nbsp;<span style='background: #fc2929 !important;color:#FFFFFF !important;padding: 1px 4px;'>bug</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/288">288 IoC 容器冲突</a>&nbsp;<span style='background: #fc2929 !important;color:#FFFFFF !important;padding: 1px 4px;'>bug</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/294">294 发布文章时允许评论开关问题</a>&nbsp;<span style='background: #fc2929 !important;color:#FFFFFF !important;padding: 1px 4px;'>bug</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/296">296 数据恢复接口被过滤器跳过</a>&nbsp;<span style='background: #fc2929 !important;color:#FFFFFF !important;padding: 1px 4px;'>bug</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/302">302 更新已发布文章问题</a>&nbsp;<span style='background: #fc2929 !important;color:#FFFFFF !important;padding: 1px 4px;'>bug</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/295">295 未初始化时启动日志报错</a>&nbsp;<span style='background: #84b6eb !important;color:#FFFFFF !important;padding: 1px 4px;'>enhancement</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/299">299 评论信息填充优化</a>&nbsp;<span style='background: #84b6eb !important;color:#FFFFFF !important;padding: 1px 4px;'>enhancement</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/316">316 评论开关页面显示</a>&nbsp;<span style='background: #84b6eb !important;color:#FFFFFF !important;padding: 1px 4px;'>enhancement</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/317">317 自动保存文章时间间隔</a>&nbsp;<span style='background: #84b6eb !important;color:#FFFFFF !important;padding: 1px 4px;'>enhancement</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/318">318 去缓存</a>&nbsp;<span style='background: #84b6eb !important;color:#FFFFFF !important;padding: 1px 4px;'>enhancement</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/320">320 加入登录状态模版变量</a>&nbsp;<span style='background: #84b6eb !important;color:#FFFFFF !important;padding: 1px 4px;'>enhancement</span></li>
</ul>
<h2>Release 0.6.1 - Aug 25, 2013</h2> <h2>Release 0.6.1 - Aug 25, 2013</h2>
<ul> <ul>
<li><a href="https://github.com/b3log/b3log-solo/issues/200">200 找回密码</a>&nbsp;<span style='background: #02e10c !important;color:#FFFFFF !important;padding: 1px 4px;'>feature</span></li> <li><a href="https://github.com/b3log/b3log-solo/issues/200">200 找回密码</a>&nbsp;<span style='background: #02e10c !important;color:#FFFFFF !important;padding: 1px 4px;'>feature</span></li>
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Description: B3log Solo core. Description: B3log Solo core.
Version: 2.0.1.4, Aug 20, 2013 Version: 2.0.1.5, Oct 29, 2013
Author: Liang Ding Author: Liang Ding
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
<parent> <parent>
<groupId>org.b3log</groupId> <groupId>org.b3log</groupId>
<artifactId>solo</artifactId> <artifactId>solo</artifactId>
<version>0.6.1</version> <version>0.6.5</version>
</parent> </parent>
<dependencies> <dependencies>
......
...@@ -35,8 +35,6 @@ import org.b3log.latke.servlet.AbstractServletListener; ...@@ -35,8 +35,6 @@ import org.b3log.latke.servlet.AbstractServletListener;
import org.b3log.latke.util.Requests; import org.b3log.latke.util.Requests;
import org.b3log.latke.util.Stopwatchs; import org.b3log.latke.util.Stopwatchs;
import org.b3log.latke.util.Strings; import org.b3log.latke.util.Strings;
import org.b3log.latke.util.freemarker.Templates;
import org.b3log.solo.event.cache.RemoveCacheListener;
import org.b3log.solo.event.comment.ArticleCommentReplyNotifier; import org.b3log.solo.event.comment.ArticleCommentReplyNotifier;
import org.b3log.solo.event.comment.PageCommentReplyNotifier; import org.b3log.solo.event.comment.PageCommentReplyNotifier;
import org.b3log.solo.event.ping.AddArticleGoogleBlogSearchPinger; import org.b3log.solo.event.ping.AddArticleGoogleBlogSearchPinger;
...@@ -59,7 +57,7 @@ import org.json.JSONObject; ...@@ -59,7 +57,7 @@ import org.json.JSONObject;
* B3log Solo servlet listener. * B3log Solo servlet listener.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.1, Aug 20, 2013 * @version 1.1.0.2, Oct 27, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
public final class SoloServletListener extends AbstractServletListener { public final class SoloServletListener extends AbstractServletListener {
...@@ -67,7 +65,7 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -67,7 +65,7 @@ public final class SoloServletListener extends AbstractServletListener {
/** /**
* B3log Solo version. * B3log Solo version.
*/ */
public static final String VERSION = "0.6.1"; public static final String VERSION = "0.6.5";
/** /**
* Logger. * Logger.
...@@ -121,8 +119,6 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -121,8 +119,6 @@ public final class SoloServletListener extends AbstractServletListener {
final Transaction transaction = preferenceRepository.beginTransaction(); final Transaction transaction = preferenceRepository.beginTransaction();
// Cache will be cleared manaully if necessary, see loadPreference.
transaction.clearQueryCache(false);
try { try {
loadPreference(); loadPreference();
...@@ -137,7 +133,9 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -137,7 +133,9 @@ public final class SoloServletListener extends AbstractServletListener {
registerEventProcessor(); registerEventProcessor();
PluginManager.getInstance().load(); final PluginManager pluginManager = beanManager.getReference(PluginManager.class);
pluginManager.load();
LOGGER.info("Initialized the context"); LOGGER.info("Initialized the context");
...@@ -162,6 +160,9 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -162,6 +160,9 @@ public final class SoloServletListener extends AbstractServletListener {
@Override @Override
public void requestInitialized(final ServletRequestEvent servletRequestEvent) { public void requestInitialized(final ServletRequestEvent servletRequestEvent) {
final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequestEvent.getServletRequest(); final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequestEvent.getServletRequest();
Requests.log(httpServletRequest, Level.DEBUG, LOGGER);
final String requestURI = httpServletRequest.getRequestURI(); final String requestURI = httpServletRequest.getRequestURI();
Stopwatchs.start("Request Initialized[requestURI=" + requestURI + "]"); Stopwatchs.start("Request Initialized[requestURI=" + requestURI + "]");
...@@ -199,12 +200,6 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -199,12 +200,6 @@ public final class SoloServletListener extends AbstractServletListener {
* *
* <p> * <p>
* Loads preference from repository, loads skins from skin directory then sets it into preference if the skins changed. * Loads preference from repository, loads skins from skin directory then sets it into preference if the skins changed.
* Puts preference into cache and persists it to repository finally.
* </p>
*
* <p>
* <b>Note</b>: Do NOT use method {@link org.b3log.solo.service.PreferenceQueryService#getPreference() } to load it, caused by the
* method may retrieve it from cache.
* </p> * </p>
*/ */
private void loadPreference() { private void loadPreference() {
...@@ -225,10 +220,6 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -225,10 +220,6 @@ public final class SoloServletListener extends AbstractServletListener {
final PreferenceMgmtService preferenceMgmtService = beanManager.getReference(PreferenceMgmtService.class); final PreferenceMgmtService preferenceMgmtService = beanManager.getReference(PreferenceMgmtService.class);
preferenceMgmtService.loadSkins(preference); preferenceMgmtService.loadSkins(preference);
final boolean pageCacheEnabled = preference.getBoolean(Preference.PAGE_CACHE_ENABLED);
Templates.enableCache(pageCacheEnabled);
} catch (final Exception e) { } catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e); LOGGER.log(Level.ERROR, e.getMessage(), e);
...@@ -246,7 +237,7 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -246,7 +237,7 @@ public final class SoloServletListener extends AbstractServletListener {
LOGGER.log(Level.INFO, "Registering event processors...."); LOGGER.log(Level.INFO, "Registering event processors....");
try { try {
final EventManager eventManager = EventManager.getInstance(); final EventManager eventManager = beanManager.getReference(EventManager.class);
// Comment // Comment
eventManager.registerListener(new ArticleCommentReplyNotifier()); eventManager.registerListener(new ArticleCommentReplyNotifier());
...@@ -261,8 +252,6 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -261,8 +252,6 @@ public final class SoloServletListener extends AbstractServletListener {
eventManager.registerListener(new ArticleSender()); eventManager.registerListener(new ArticleSender());
eventManager.registerListener(new ArticleUpdater()); eventManager.registerListener(new ArticleUpdater());
eventManager.registerListener(new CommentSender()); eventManager.registerListener(new CommentSender());
// Cache
eventManager.registerListener(new RemoveCacheListener());
} catch (final Exception e) { } catch (final Exception e) {
LOGGER.log(Level.ERROR, "Register event processors error", e); LOGGER.log(Level.ERROR, "Register event processors error", e);
throw new IllegalStateException(e); throw new IllegalStateException(e);
......
...@@ -51,7 +51,6 @@ import org.b3log.solo.service.PreferenceQueryService; ...@@ -51,7 +51,6 @@ import org.b3log.solo.service.PreferenceQueryService;
import org.b3log.solo.service.StatisticMgmtService; import org.b3log.solo.service.StatisticMgmtService;
import org.b3log.solo.util.Comments; import org.b3log.solo.util.Comments;
import org.b3log.solo.util.QueryResults; import org.b3log.solo.util.QueryResults;
import org.b3log.solo.util.TimeZones;
import org.json.JSONObject; import org.json.JSONObject;
...@@ -59,7 +58,7 @@ import org.json.JSONObject; ...@@ -59,7 +58,7 @@ import org.json.JSONObject;
* Comment receiver (from B3log Symphony). * Comment receiver (from B3log Symphony).
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.7, Jul 10, 2013 * @version 1.0.0.8, Aug 29, 2013
* @since 0.5.5 * @since 0.5.5
*/ */
@RequestProcessor @RequestProcessor
...@@ -79,6 +78,7 @@ public class CommentReceiver { ...@@ -79,6 +78,7 @@ public class CommentReceiver {
/** /**
* Comment repository. * Comment repository.
*/ */
@Inject
private static CommentRepository commentRepository; private static CommentRepository commentRepository;
/** /**
...@@ -112,7 +112,8 @@ public class CommentReceiver { ...@@ -112,7 +112,8 @@ public class CommentReceiver {
/** /**
* Event manager. * Event manager.
*/ */
private static EventManager eventManager = EventManager.getInstance(); @Inject
private static EventManager eventManager;
/** /**
* Statistic management service. * Statistic management service.
...@@ -218,8 +219,7 @@ public class CommentReceiver { ...@@ -218,8 +219,7 @@ public class CommentReceiver {
comment.put(Comment.COMMENT_EMAIL, commentEmail); comment.put(Comment.COMMENT_EMAIL, commentEmail);
comment.put(Comment.COMMENT_URL, commentURL); comment.put(Comment.COMMENT_URL, commentURL);
comment.put(Comment.COMMENT_CONTENT, commentContent); comment.put(Comment.COMMENT_CONTENT, commentContent);
final String timeZoneId = preference.getString(Preference.TIME_ZONE_ID); final Date date = new Date();
final Date date = TimeZones.getTime(timeZoneId);
comment.put(Comment.COMMENT_DATE, date); comment.put(Comment.COMMENT_DATE, date);
ret.put(Comment.COMMENT_DATE, DateFormatUtils.format(date, "yyyy-MM-dd hh:mm:ss")); ret.put(Comment.COMMENT_DATE, DateFormatUtils.format(date, "yyyy-MM-dd hh:mm:ss"));
......
/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.event.cache;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.service.ServiceException;
import org.b3log.solo.service.StatisticMgmtService;
/**
* This listener is responsible for handling remove cache event.
*
* <p>
* Flush the statistic to repository.
* </p>
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.1, Nov 28, 2011
* @since 0.3.1
*/
public final class RemoveCacheListener extends AbstractEventListener<Void> {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(RemoveCacheListener.class.getName());
@Override
public void action(final Event<Void> event) throws EventException {
LOGGER.log(Level.DEBUG, "Processing an event[type={0} in listener[className={2}]",
new Object[] {event.getType(), RemoveCacheListener.class.getName()});
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final StatisticMgmtService statisticMgmtService = beanManager.getReference(StatisticMgmtService.class);
try {
statisticMgmtService.flushStatistic();
} catch (final ServiceException e) {
LOGGER.log(Level.ERROR, "Flushes statistic to repository failed", e);
}
}
/**
* Gets the event type {@linkplain PageCaches#REMOVE_CACHE}.
*
* @return event type
*/
@Override
public String getEventType() {
return PageCaches.REMOVE_CACHE;
}
}
...@@ -58,7 +58,6 @@ public final class PluginRefresher extends AbstractEventListener<List<AbstractPl ...@@ -58,7 +58,6 @@ public final class PluginRefresher extends AbstractEventListener<List<AbstractPl
final Transaction transaction = pluginRepository.beginTransaction(); final Transaction transaction = pluginRepository.beginTransaction();
transaction.clearQueryCache(false);
try { try {
final PluginMgmtService pluginMgmtService = beanManager.getReference(PluginMgmtService.class); final PluginMgmtService pluginMgmtService = beanManager.getReference(PluginMgmtService.class);
......
...@@ -103,11 +103,11 @@ public final class ArticleSender extends AbstractEventListener<JSONObject> { ...@@ -103,11 +103,11 @@ public final class ArticleSender extends AbstractEventListener<JSONObject> {
throw new EventException("Not found preference"); throw new EventException("Not found preference");
} }
if (Latkes.getServePath().contains("localhost")) { // if (Latkes.getServePath().contains("localhost")) {
LOGGER.log(Level.INFO, "Blog Solo runs on local server, so should not send this article[id={0}, title={1}] to Rhythm", // LOGGER.log(Level.INFO, "Blog Solo runs on local server, so should not send this article[id={0}, title={1}] to Rhythm",
new Object[] {originalArticle.getString(Keys.OBJECT_ID), originalArticle.getString(Article.ARTICLE_TITLE)}); // new Object[] {originalArticle.getString(Keys.OBJECT_ID), originalArticle.getString(Article.ARTICLE_TITLE)});
return; // return;
} // }
final HTTPRequest httpRequest = new HTTPRequest(); final HTTPRequest httpRequest = new HTTPRequest();
......
...@@ -102,11 +102,11 @@ public final class ArticleUpdater extends AbstractEventListener<JSONObject> { ...@@ -102,11 +102,11 @@ public final class ArticleUpdater extends AbstractEventListener<JSONObject> {
throw new EventException("Not found preference"); throw new EventException("Not found preference");
} }
if (Latkes.getServePath().contains("localhost")) { // if (Latkes.getServePath().contains("localhost")) {
LOGGER.log(Level.INFO, "Blog Solo runs on local server, so should not send this article[id={0}, title={1}] to Rhythm", // LOGGER.log(Level.INFO, "Blog Solo runs on local server, so should not send this article[id={0}, title={1}] to Rhythm",
new Object[] {originalArticle.getString(Keys.OBJECT_ID), originalArticle.getString(Article.ARTICLE_TITLE)}); // new Object[] {originalArticle.getString(Keys.OBJECT_ID), originalArticle.getString(Article.ARTICLE_TITLE)});
return; // return;
} // }
final HTTPRequest httpRequest = new HTTPRequest(); final HTTPRequest httpRequest = new HTTPRequest();
......
...@@ -31,20 +31,19 @@ import org.b3log.latke.ioc.LatkeBeanManager; ...@@ -31,20 +31,19 @@ import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle; import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.service.ServiceException; import org.b3log.latke.servlet.DispatcherServlet;
import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestDispatcher;
import org.b3log.latke.servlet.HTTPRequestMethod; import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.HttpControl;
import org.b3log.latke.servlet.renderer.HTTP500Renderer;
import org.b3log.solo.service.InitService; import org.b3log.solo.service.InitService;
import org.b3log.solo.service.PreferenceQueryService;
import org.json.JSONObject;
/** /**
* Checks initialization filter. * Checks initialization filter.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.1.0, Jun 28, 2013 * @version 1.0.1.1, Sep 10, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
public final class InitCheckFilter implements Filter { public final class InitCheckFilter implements Filter {
...@@ -74,8 +73,8 @@ public final class InitCheckFilter implements Filter { ...@@ -74,8 +73,8 @@ public final class InitCheckFilter implements Filter {
LOGGER.log(Level.TRACE, "Request[URI={0}]", requestURI); LOGGER.log(Level.TRACE, "Request[URI={0}]", requestURI);
if (requestURI.startsWith("/latke/remote")) { // If requests Latke Remote APIs, skips this filter
// If requests Latke Remote APIs, skips this filter if (requestURI.startsWith(Latkes.getContextPath() + "/latke/remote")) {
chain.doFilter(request, response); chain.doFilter(request, response);
return; return;
...@@ -83,45 +82,39 @@ public final class InitCheckFilter implements Filter { ...@@ -83,45 +82,39 @@ public final class InitCheckFilter implements Filter {
final LatkeBeanManager beanManager = Lifecycle.getBeanManager(); final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final InitService initService = beanManager.getReference(InitService.class); final InitService initService = beanManager.getReference(InitService.class);
try {
if (initService.isInited()) {
chain.doFilter(request, response);
return; if (initService.isInited()) {
} chain.doFilter(request, response);
if ("POST".equalsIgnoreCase(httpServletRequest.getMethod()) && (Latkes.getContextPath() + "/init").equals(requestURI)) { return;
// Do initailization }
chain.doFilter(request, response);
return; if ("POST".equalsIgnoreCase(httpServletRequest.getMethod()) && (Latkes.getContextPath() + "/init").equals(requestURI)) {
} // Do initailization
chain.doFilter(request, response);
final PreferenceQueryService preferenceQueryService = beanManager.getReference(PreferenceQueryService.class); return;
}
LOGGER.debug("Try to get preference to confirm whether the preference exixts"); LOGGER.log(Level.INFO, "B3log Solo has not been initialized, so redirects to /init");
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) { final HTTPRequestContext context = new HTTPRequestContext();
LOGGER.log(Level.WARN, "B3log Solo has not been initialized, so redirects to /init");
final HTTPRequestContext context = new HTTPRequestContext(); context.setRequest((HttpServletRequest) request);
context.setResponse((HttpServletResponse) response);
context.setRequest((HttpServletRequest) request); request.setAttribute(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/init");
context.setResponse((HttpServletResponse) response); request.setAttribute(Keys.HttpRequest.REQUEST_METHOD, HTTPRequestMethod.GET.name());
request.setAttribute(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/init"); final HttpControl httpControl = new HttpControl(DispatcherServlet.SYS_HANDLER.iterator(), context);
request.setAttribute(Keys.HttpRequest.REQUEST_METHOD, HTTPRequestMethod.GET.name());
HTTPRequestDispatcher.dispatch(context); try {
} else { httpControl.nextHandler();
// XXX: Wrong state of SoloServletListener.isInited() } catch (final Exception e) {
chain.doFilter(request, response); context.setRenderer(new HTTP500Renderer(e));
}
} catch (final ServiceException e) {
((HttpServletResponse) response).sendError(HttpServletResponse.SC_NOT_FOUND);
} }
DispatcherServlet.result(context);
} }
@Override @Override
......
/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.filter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.time.DateFormatUtils;
import org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.service.LangPropsService;
import org.b3log.latke.service.LangPropsServiceImpl;
import org.b3log.latke.service.ServiceException;
import org.b3log.latke.util.StaticResources;
import org.b3log.latke.util.Strings;
import org.b3log.solo.model.Article;
import org.b3log.solo.model.Common;
import org.b3log.solo.model.PageTypes;
import org.b3log.solo.processor.util.TopBars;
import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.impl.ArticleRepositoryImpl;
import org.b3log.solo.service.ArticleQueryService;
import org.b3log.solo.service.StatisticMgmtService;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Page cache filter.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.1.1, Jan 8, 2013
* @since 0.3.1
*/
public final class PageCacheFilter implements Filter {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(PageCacheFilter.class.getName());
@Override
public void init(final FilterConfig filterConfig) throws ServletException {}
/**
* Try to write response from cache.
*
* @param request the specified request
* @param response the specified response
* @param chain filter chain
* @throws IOException io exception
* @throws ServletException servlet exception
*/
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
final long startTimeMillis = System.currentTimeMillis();
request.setAttribute(Keys.HttpRequest.START_TIME_MILLIS, startTimeMillis);
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final String requestURI = httpServletRequest.getRequestURI();
LOGGER.log(Level.DEBUG, "Request URI[{0}]", requestURI);
if (StaticResources.isStatic(httpServletRequest)) {
final String path = httpServletRequest.getServletPath() + httpServletRequest.getPathInfo();
LOGGER.log(Level.TRACE, "Requests a static resource, forwards to servlet[path={0}]", path);
request.getRequestDispatcher(path).forward(request, response);
return;
}
if (!Latkes.isPageCacheEnabled()) {
LOGGER.log(Level.TRACE, "Page cache is disabled");
chain.doFilter(request, response);
return;
}
final String skinDirName = (String) httpServletRequest.getAttribute(Keys.TEMAPLTE_DIR_NAME);
if ("mobile".equals(skinDirName)) {
// Mobile request, bypasses page caching
chain.doFilter(request, response);
return;
}
String pageCacheKey;
final String queryString = httpServletRequest.getQueryString();
pageCacheKey = (String) request.getAttribute(Keys.PAGE_CACHE_KEY);
if (Strings.isEmptyOrNull(pageCacheKey)) {
pageCacheKey = PageCaches.getPageCacheKey(requestURI, queryString);
request.setAttribute(Keys.PAGE_CACHE_KEY, pageCacheKey);
}
final JSONObject cachedPageContentObject = PageCaches.get(pageCacheKey, httpServletRequest, (HttpServletResponse) response);
if (null == cachedPageContentObject) {
LOGGER.log(Level.DEBUG, "Page cache miss for request URI[{0}]", requestURI);
chain.doFilter(request, response);
return;
}
final String cachedType = cachedPageContentObject.optString(PageCaches.CACHED_TYPE);
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final ArticleQueryService articleQueryService = beanManager.getReference(ArticleQueryService.class);
final LangPropsService langPropsService = beanManager.getReference(LangPropsServiceImpl.class);
try {
// If cached an article that has view password, dispatches the password form
if (langPropsService.get(PageTypes.ARTICLE.getLangeLabel()).equals(cachedType)
&& cachedPageContentObject.has(PageCaches.CACHED_PWD)) {
JSONObject article = new JSONObject();
final String articleId = cachedPageContentObject.optString(PageCaches.CACHED_OID);
article.put(Keys.OBJECT_ID, articleId);
article.put(Article.ARTICLE_VIEW_PWD, cachedPageContentObject.optString(PageCaches.CACHED_PWD));
if (articleQueryService.needViewPwd(httpServletRequest, article)) {
final ArticleRepository articleRepository = beanManager.getReference(ArticleRepositoryImpl.class);
article = articleRepository.get(articleId); // Loads the article entity
final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
try {
httpServletResponse.sendRedirect(
Latkes.getServePath() + "/console/article-pwd?articleId=" + article.optString(Keys.OBJECT_ID));
return;
} catch (final Exception e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
}
}
} catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
chain.doFilter(request, response);
}
try {
LOGGER.log(Level.TRACE, "Writes resposne for page[pageCacheKey={0}] from cache", pageCacheKey);
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
final PrintWriter writer = response.getWriter();
String cachedPageContent = cachedPageContentObject.getString(PageCaches.CACHED_CONTENT);
final TopBars topbars = beanManager.getReference(TopBars.class);
final String topBarHTML = topbars.getTopBarHTML((HttpServletRequest) request, (HttpServletResponse) response);
cachedPageContent = cachedPageContent.replace(Common.TOP_BAR_REPLACEMENT_FLAG, topBarHTML);
final String cachedTitle = cachedPageContentObject.getString(PageCaches.CACHED_TITLE);
LOGGER.log(Level.TRACE, "Cached value[key={0}, type={1}, title={2}]", new Object[] {pageCacheKey, cachedType, cachedTitle});
final StatisticMgmtService statisticMgmtService = beanManager.getReference(StatisticMgmtService.class);
statisticMgmtService.incBlogViewCount((HttpServletRequest) request, (HttpServletResponse) response);
final long endimeMillis = System.currentTimeMillis();
final String dateString = DateFormatUtils.format(endimeMillis, "yyyy/MM/dd HH:mm:ss");
final String msg = String.format("<!-- Cached by B3log Solo(%1$d ms), %2$s -->", endimeMillis - startTimeMillis, dateString);
LOGGER.debug(msg);
cachedPageContent += Strings.LINE_SEPARATOR + msg;
writer.write(cachedPageContent);
writer.flush();
writer.close();
} catch (final JSONException e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
chain.doFilter(request, response);
} catch (final RepositoryException e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
chain.doFilter(request, response);
} catch (final ServiceException e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
chain.doFilter(request, response);
}
}
@Override
public void destroy() {}
}
...@@ -33,9 +33,11 @@ import org.b3log.latke.ioc.Lifecycle; ...@@ -33,9 +33,11 @@ import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.repository.RepositoryException; import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.servlet.DispatcherServlet;
import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestDispatcher;
import org.b3log.latke.servlet.HTTPRequestMethod; import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.HttpControl;
import org.b3log.latke.servlet.renderer.HTTP500Renderer;
import org.b3log.solo.model.Article; import org.b3log.solo.model.Article;
import org.b3log.solo.model.Page; import org.b3log.solo.model.Page;
import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.repository.ArticleRepository;
...@@ -102,7 +104,6 @@ public final class PermalinkFilter implements Filter { ...@@ -102,7 +104,6 @@ public final class PermalinkFilter implements Filter {
final LatkeBeanManager beanManager = Lifecycle.getBeanManager(); final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
try { try {
final ArticleRepository articleRepository = beanManager.getReference(ArticleRepositoryImpl.class); final ArticleRepository articleRepository = beanManager.getReference(ArticleRepositoryImpl.class);
article = articleRepository.getByPermalink(permalink); article = articleRepository.getByPermalink(permalink);
...@@ -173,7 +174,15 @@ public final class PermalinkFilter implements Filter { ...@@ -173,7 +174,15 @@ public final class PermalinkFilter implements Filter {
request.setAttribute(Keys.HttpRequest.REQUEST_METHOD, HTTPRequestMethod.GET.name()); request.setAttribute(Keys.HttpRequest.REQUEST_METHOD, HTTPRequestMethod.GET.name());
HTTPRequestDispatcher.dispatch(context); final HttpControl httpControl = new HttpControl(DispatcherServlet.SYS_HANDLER.iterator(), context);
try {
httpControl.nextHandler();
} catch (final Exception e) {
context.setRenderer(new HTTP500Renderer(e));
}
DispatcherServlet.result(context);
} }
@Override @Override
......
/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.model;
/**
* This class defines all cache model relevant keys.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.2, Dec 27, 2010
*/
public final class Cache {
/**
* Cache.
*/
public static final String CACHE = "cache";
/**
* Cached count.
*/
public static final String CACHE_CACHED_COUNT = "cacheCachedCount";
/**
* Cache hit count.
*/
public static final String CACHE_HIT_COUNT = "cacheHitCount";
/**
* Cache hit bytes.
*/
public static final String CACHE_HIT_BYTES = "cacheHitBytes";
/**
* Cached bytes.
*/
public static final String CACHE_CACHED_BYTES = "cacheCachedBytes";
/**
* Cache miss count.
*/
public static final String CACHE_MISS_COUNT = "cacheMissCount";
/**
* Private default constructor.
*/
private Cache() {}
}
...@@ -221,11 +221,6 @@ public final class Common { ...@@ -221,11 +221,6 @@ public final class Common {
*/ */
public static final String POST_TO_COMMUNITY = "postToCommunity"; public static final String POST_TO_COMMUNITY = "postToCommunity";
/**
* Key of page cached count.
*/
public static final String PAGE_CACHED_CNT = "pageCachedCnt";
/** /**
* Key of mini postfix. * Key of mini postfix.
*/ */
...@@ -269,12 +264,7 @@ public final class Common { ...@@ -269,12 +264,7 @@ public final class Common {
/** /**
* Key of top bar replacement flag. * Key of top bar replacement flag.
*/ */
public static final String TOP_BAR_REPLACEMENT_FLAG_KEY = "topBarReplacement"; public static final String TOP_BAR = "topBarReplacement";
/**
* Top bar replacement flag.
*/
public static final String TOP_BAR_REPLACEMENT_FLAG = "#B3logSolo#topBarReplacement#B3logSolo#";
/** /**
* Key of unused tags. * Key of unused tags.
......
...@@ -17,8 +17,6 @@ package org.b3log.solo.model; ...@@ -17,8 +17,6 @@ package org.b3log.solo.model;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.RuntimeEnv;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.json.JSONArray; import org.json.JSONArray;
...@@ -149,11 +147,6 @@ public final class Preference { ...@@ -149,11 +147,6 @@ public final class Preference {
*/ */
public static final String KEY_OF_SOLO = "keyOfSolo"; public static final String KEY_OF_SOLO = "keyOfSolo";
/**
* Key of page cache enabled.
*/
public static final String PAGE_CACHE_ENABLED = "pageCacheEnabled";
/** /**
* Key of allow visit draft via permalink. * Key of allow visit draft via permalink.
*/ */
...@@ -345,11 +338,6 @@ public final class Preference { ...@@ -345,11 +338,6 @@ public final class Preference {
*/ */
public static final String DEFAULT_SIGNS; public static final String DEFAULT_SIGNS;
/**
* Default page cache enabled.
*/
public static final boolean DEFAULT_PAGE_CACHE_ENABLED;
/** /**
* Default allow visit draft via permalink. * Default allow visit draft via permalink.
*/ */
...@@ -422,12 +410,6 @@ public final class Preference { ...@@ -422,12 +410,6 @@ public final class Preference {
"Your comment on post[<a href='${postLink}'>" + "${postTitle}</a>] received an reply: <p>${replier}" "Your comment on post[<a href='${postLink}'>" + "${postTitle}</a>] received an reply: <p>${replier}"
+ ": <span><a href='${replyURL}'>${replyContent}</a></span></p>"); + ": <span><a href='${replyURL}'>${replyContent}</a></span></p>");
DEFAULT_REPLY_NOTIFICATION_TEMPLATE = replyNotificationTemplate.toString(); DEFAULT_REPLY_NOTIFICATION_TEMPLATE = replyNotificationTemplate.toString();
if (RuntimeEnv.BAE == Latkes.getRuntimeEnv()) {
DEFAULT_PAGE_CACHE_ENABLED = false; // https://github.com/b3log/b3log-solo/issues/73
} else {
DEFAULT_PAGE_CACHE_ENABLED = true;
}
} catch (final Exception e) { } catch (final Exception e) {
LOGGER.log(Level.ERROR, "Creates sign error!", e); LOGGER.log(Level.ERROR, "Creates sign error!", e);
throw new IllegalStateException(e); throw new IllegalStateException(e);
......
...@@ -28,7 +28,6 @@ import org.apache.commons.lang.StringUtils; ...@@ -28,7 +28,6 @@ import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils; import org.apache.commons.lang.time.DateFormatUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.Latkes; import org.b3log.latke.Latkes;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.model.Pagination; import org.b3log.latke.model.Pagination;
...@@ -43,6 +42,7 @@ import org.b3log.latke.servlet.annotation.RequestProcessor; ...@@ -43,6 +42,7 @@ import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.JSONRenderer; import org.b3log.latke.servlet.renderer.JSONRenderer;
import org.b3log.latke.servlet.renderer.TextHTMLRenderer; import org.b3log.latke.servlet.renderer.TextHTMLRenderer;
import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer; import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer;
import org.b3log.latke.servlet.renderer.freemarker.FreeMarkerRenderer;
import org.b3log.latke.util.Dates; import org.b3log.latke.util.Dates;
import org.b3log.latke.util.Locales; import org.b3log.latke.util.Locales;
import org.b3log.latke.util.Paginator; import org.b3log.latke.util.Paginator;
...@@ -52,7 +52,6 @@ import org.b3log.latke.util.Strings; ...@@ -52,7 +52,6 @@ import org.b3log.latke.util.Strings;
import org.b3log.solo.SoloServletListener; import org.b3log.solo.SoloServletListener;
import org.b3log.solo.model.*; import org.b3log.solo.model.*;
import org.b3log.solo.processor.renderer.ConsoleRenderer; import org.b3log.solo.processor.renderer.ConsoleRenderer;
import org.b3log.solo.processor.renderer.FrontRenderer;
import org.b3log.solo.processor.util.Filler; import org.b3log.solo.processor.util.Filler;
import org.b3log.solo.service.*; import org.b3log.solo.service.*;
import org.b3log.solo.util.Skins; import org.b3log.solo.util.Skins;
...@@ -67,7 +66,7 @@ import org.jsoup.Jsoup; ...@@ -67,7 +66,7 @@ import org.jsoup.Jsoup;
* Article processor. * Article processor.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.2.11, Jul 11, 2013 * @version 1.1.2.13, Oct 26, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
@RequestProcessor @RequestProcessor
...@@ -647,7 +646,7 @@ public class ArticleProcessor { ...@@ -647,7 +646,7 @@ public class ArticleProcessor {
@RequestProcessing(value = "/authors/**", method = HTTPRequestMethod.GET) @RequestProcessing(value = "/authors/**", method = HTTPRequestMethod.GET)
public void showAuthorArticles(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) public void showAuthorArticles(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response)
throws IOException, JSONException { throws IOException, JSONException {
final AbstractFreeMarkerRenderer renderer = new FrontRenderer(); final AbstractFreeMarkerRenderer renderer = new FreeMarkerRenderer();
context.setRenderer(renderer); context.setRenderer(renderer);
...@@ -693,16 +692,6 @@ public class ArticleProcessor { ...@@ -693,16 +692,6 @@ public class ArticleProcessor {
} }
final JSONObject author = result.getJSONObject(User.USER); final JSONObject author = result.getJSONObject(User.USER);
final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale());
request.setAttribute(PageCaches.CACHED_TYPE, langs.get(PageTypes.AUTHOR_ARTICLES.getLangeLabel()));
request.setAttribute(PageCaches.CACHED_OID, "No id");
request.setAttribute(PageCaches.CACHED_TITLE,
langs.get(PageTypes.AUTHOR_ARTICLES.getLangeLabel()) + " [" + langs.get("pageNumLabel") + "=" + currentPageNum + ", "
+ langs.get("authorLabel") + "=" + author.getString(User.USER_NAME) + "]");
request.setAttribute(PageCaches.CACHED_LINK, requestURI);
final String authorEmail = author.getString(User.USER_EMAIL); final String authorEmail = author.getString(User.USER_EMAIL);
final List<JSONObject> articles = articleQueryService.getArticlesByAuthorEmail(authorEmail, currentPageNum, pageSize); final List<JSONObject> articles = articleQueryService.getArticlesByAuthorEmail(authorEmail, currentPageNum, pageSize);
...@@ -731,8 +720,7 @@ public class ArticleProcessor { ...@@ -731,8 +720,7 @@ public class ArticleProcessor {
final Map<String, Object> dataModel = renderer.getDataModel(); final Map<String, Object> dataModel = renderer.getDataModel();
prepareShowAuthorArticles(pageNums, dataModel, pageCount, currentPageNum, articles, author); prepareShowAuthorArticles(pageNums, dataModel, pageCount, currentPageNum, articles, author);
dataModel.put(Keys.PAGE_TYPE, PageTypes.AUTHOR_ARTICLES); filler.fillBlogHeader(request, response, dataModel, preference);
filler.fillBlogHeader(request, dataModel, preference);
filler.fillBlogFooter(request, dataModel, preference); filler.fillBlogFooter(request, dataModel, preference);
filler.fillSide(request, dataModel, preference); filler.fillSide(request, dataModel, preference);
Skins.fillLangs(preference.optString(Preference.LOCALE_STRING), (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), dataModel); Skins.fillLangs(preference.optString(Preference.LOCALE_STRING), (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), dataModel);
...@@ -757,7 +745,7 @@ public class ArticleProcessor { ...@@ -757,7 +745,7 @@ public class ArticleProcessor {
@RequestProcessing(value = "/archives/**", method = HTTPRequestMethod.GET) @RequestProcessing(value = "/archives/**", method = HTTPRequestMethod.GET)
public void showArchiveArticles(final HTTPRequestContext context, public void showArchiveArticles(final HTTPRequestContext context,
final HttpServletRequest request, final HttpServletResponse response) { final HttpServletRequest request, final HttpServletResponse response) {
final AbstractFreeMarkerRenderer renderer = new FrontRenderer(); final AbstractFreeMarkerRenderer renderer = new FreeMarkerRenderer();
context.setRenderer(renderer); context.setRenderer(renderer);
...@@ -825,20 +813,10 @@ public class ArticleProcessor { ...@@ -825,20 +813,10 @@ public class ArticleProcessor {
Skins.fillLangs(preference.optString(Preference.LOCALE_STRING), (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), dataModel); Skins.fillLangs(preference.optString(Preference.LOCALE_STRING), (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), dataModel);
final String cachedTitle = prepareShowArchiveArticles(preference, dataModel, articles, currentPageNum, pageCount, prepareShowArchiveArticles(preference, dataModel, articles, currentPageNum, pageCount, archiveDateString, archiveDate);
archiveDateString, archiveDate); filler.fillBlogHeader(request, response, dataModel, preference);
dataModel.put(Keys.PAGE_TYPE, PageTypes.DATE_ARTICLES);
filler.fillBlogHeader(request, dataModel, preference);
filler.fillBlogFooter(request, dataModel, preference); filler.fillBlogFooter(request, dataModel, preference);
filler.fillSide(request, dataModel, preference); filler.fillSide(request, dataModel, preference);
final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale());
request.setAttribute(PageCaches.CACHED_TYPE, langs.get(PageTypes.DATE_ARTICLES.getLangeLabel()));
request.setAttribute(PageCaches.CACHED_OID, archiveDateId);
request.setAttribute(PageCaches.CACHED_TITLE, cachedTitle + " [" + langs.get("pageNumLabel") + "=" + currentPageNum + "]");
request.setAttribute(PageCaches.CACHED_LINK, requestURI);
} catch (final Exception e) { } catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e); LOGGER.log(Level.ERROR, e.getMessage(), e);
...@@ -895,7 +873,7 @@ public class ArticleProcessor { ...@@ -895,7 +873,7 @@ public class ArticleProcessor {
final String articleId = article.optString(Keys.OBJECT_ID); final String articleId = article.optString(Keys.OBJECT_ID);
LOGGER.log(Level.DEBUG, "Article[id={0}]", articleId); LOGGER.log(Level.DEBUG, "Article[id={0}]", articleId);
final AbstractFreeMarkerRenderer renderer = new FrontRenderer(); final AbstractFreeMarkerRenderer renderer = new FreeMarkerRenderer();
context.setRenderer(renderer); context.setRenderer(renderer);
renderer.setTemplateName("article.ftl"); renderer.setTemplateName("article.ftl");
...@@ -917,12 +895,6 @@ public class ArticleProcessor { ...@@ -917,12 +895,6 @@ public class ArticleProcessor {
final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale()); final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale());
request.setAttribute(PageCaches.CACHED_TYPE, langs.get(PageTypes.ARTICLE.getLangeLabel()));
request.setAttribute(PageCaches.CACHED_OID, articleId);
request.setAttribute(PageCaches.CACHED_TITLE, article.getString(Article.ARTICLE_TITLE));
request.setAttribute(PageCaches.CACHED_LINK, article.getString(Article.ARTICLE_PERMALINK));
request.setAttribute(PageCaches.CACHED_PWD, article.optString(Article.ARTICLE_VIEW_PWD));
// For <meta name="description" content="${article.articleAbstract}"/> // For <meta name="description" content="${article.articleAbstract}"/>
final String metaDescription = Jsoup.parse(article.optString(Article.ARTICLE_ABSTRACT)).text(); final String metaDescription = Jsoup.parse(article.optString(Article.ARTICLE_ABSTRACT)).text();
...@@ -947,9 +919,7 @@ public class ArticleProcessor { ...@@ -947,9 +919,7 @@ public class ArticleProcessor {
prepareShowArticle(preference, dataModel, article); prepareShowArticle(preference, dataModel, article);
dataModel.put(Keys.PAGE_TYPE, PageTypes.ARTICLE); filler.fillBlogHeader(request, response, dataModel, preference);
filler.fillBlogHeader(request, dataModel, preference);
filler.fillBlogFooter(request, dataModel, preference); filler.fillBlogFooter(request, dataModel, preference);
filler.fillSide(request, dataModel, preference); filler.fillSide(request, dataModel, preference);
Skins.fillLangs(preference.optString(Preference.LOCALE_STRING), (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), dataModel); Skins.fillLangs(preference.optString(Preference.LOCALE_STRING), (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), dataModel);
...@@ -1272,7 +1242,7 @@ public class ArticleProcessor { ...@@ -1272,7 +1242,7 @@ public class ArticleProcessor {
*/ */
private void prepareShowArticle(final JSONObject preference, final Map<String, Object> dataModel, final JSONObject article) private void prepareShowArticle(final JSONObject preference, final Map<String, Object> dataModel, final JSONObject article)
throws Exception { throws Exception {
article.put(Common.COMMENTABLE, article.getBoolean(Article.ARTICLE_COMMENTABLE)); article.put(Common.COMMENTABLE, preference.getBoolean(Preference.COMMENTABLE) && article.getBoolean(Article.ARTICLE_COMMENTABLE));
article.put(Common.PERMALINK, article.getString(Article.ARTICLE_PERMALINK)); article.put(Common.PERMALINK, article.getString(Article.ARTICLE_PERMALINK));
dataModel.put(Article.ARTICLE, article); dataModel.put(Article.ARTICLE, article);
final String articleId = article.getString(Keys.OBJECT_ID); final String articleId = article.getString(Keys.OBJECT_ID);
......
/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.processor;
import java.io.IOException;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.annotation.RequestProcessing;
import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.DoNothingRenderer;
import org.b3log.latke.util.Requests;
import org.b3log.latke.util.Strings;
import org.b3log.solo.model.Common;
import org.b3log.solo.service.UserMgmtService;
import org.b3log.solo.service.UserQueryService;
import org.json.JSONObject;
/**
* Cache processor.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.2, Aug 9, 2012
* @since 0.3.1
*/
@RequestProcessor
public class CacheProcessor {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(CacheProcessor.class.getName());
/**
* User query service.
*/
@Inject
private UserQueryService userQueryService;
/**
* User management service.
*/
@Inject
private UserMgmtService userMgmtService;
/**
* Clears cache with the specified context.
*
* @param context the specified context
* @param request the specified HTTP servlet request
* @param response the specified HTTP servlet response
* @throws IOException io exception
*/
@RequestProcessing(value = "/clear-cache.do", method = HTTPRequestMethod.POST)
public void clearCache(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response)
throws IOException {
userMgmtService.tryLogInWithCookie(request, response);
if (!userQueryService.isAdminLoggedIn(request)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
try {
final JSONObject requestJSONObject = Requests.parseRequestJSONObject(request, response);
final String all = requestJSONObject.optString("all");
if (Strings.isEmptyOrNull(all)) { // Just clears single page cache
final String uri = requestJSONObject.optString(Common.URI);
clearPageCache(uri);
} else { // Clears all page caches
clearAllPageCache();
}
context.setRenderer(new DoNothingRenderer());
} catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
}
}
/**
* Clears a page cache specified by the given URI.
*
* @param uri the specified URI
*/
private void clearPageCache(final String uri) {
final String pageCacheKey = PageCaches.getPageCacheKey(uri, null);
LOGGER.log(Level.INFO, "Clears page cache[pageCacheKey={0}]", pageCacheKey);
PageCaches.remove(pageCacheKey);
}
/**
* Clears all page cache.
*/
private void clearAllPageCache() {
PageCaches.removeAll();
}
}
...@@ -25,6 +25,7 @@ import javax.servlet.http.HttpSession; ...@@ -25,6 +25,7 @@ import javax.servlet.http.HttpSession;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.model.User;
import org.b3log.latke.service.LangPropsService; import org.b3log.latke.service.LangPropsService;
import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestMethod; import org.b3log.latke.servlet.HTTPRequestMethod;
...@@ -33,6 +34,7 @@ import org.b3log.latke.servlet.annotation.RequestProcessor; ...@@ -33,6 +34,7 @@ import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.JSONRenderer; import org.b3log.latke.servlet.renderer.JSONRenderer;
import org.b3log.latke.util.Requests; import org.b3log.latke.util.Requests;
import org.b3log.solo.model.Article; import org.b3log.solo.model.Article;
import org.b3log.solo.model.Comment;
import org.b3log.solo.model.Common; import org.b3log.solo.model.Common;
import org.b3log.solo.model.Page; import org.b3log.solo.model.Page;
import org.b3log.solo.service.CommentMgmtService; import org.b3log.solo.service.CommentMgmtService;
...@@ -45,7 +47,7 @@ import org.json.JSONObject; ...@@ -45,7 +47,7 @@ import org.json.JSONObject;
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author ArmstrongCN * @author ArmstrongCN
* @version 1.1.0.11, Jan 30, 2013 * @version 1.1.0.12, Oct 26, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
@RequestProcessor @RequestProcessor
...@@ -113,6 +115,8 @@ public class CommentProcessor { ...@@ -113,6 +115,8 @@ public class CommentProcessor {
requestJSONObject.put(Common.TYPE, Page.PAGE); requestJSONObject.put(Common.TYPE, Page.PAGE);
fillCommenter(requestJSONObject, httpServletRequest);
final JSONObject jsonObject = commentMgmtService.checkAddCommentRequest(requestJSONObject); final JSONObject jsonObject = commentMgmtService.checkAddCommentRequest(requestJSONObject);
final JSONRenderer renderer = new JSONRenderer(); final JSONRenderer renderer = new JSONRenderer();
...@@ -196,7 +200,7 @@ public class CommentProcessor { ...@@ -196,7 +200,7 @@ public class CommentProcessor {
* @throws ServletException servlet exception * @throws ServletException servlet exception
* @throws IOException io exception * @throws IOException io exception
*/ */
@RequestProcessing(value = { "/add-article-comment.do"}, method = HTTPRequestMethod.POST) @RequestProcessing(value = "/add-article-comment.do", method = HTTPRequestMethod.POST)
public void addArticleComment(final HTTPRequestContext context) throws ServletException, IOException { public void addArticleComment(final HTTPRequestContext context) throws ServletException, IOException {
final HttpServletRequest httpServletRequest = context.getRequest(); final HttpServletRequest httpServletRequest = context.getRequest();
final HttpServletResponse httpServletResponse = context.getResponse(); final HttpServletResponse httpServletResponse = context.getResponse();
...@@ -205,6 +209,8 @@ public class CommentProcessor { ...@@ -205,6 +209,8 @@ public class CommentProcessor {
requestJSONObject.put(Common.TYPE, Article.ARTICLE); requestJSONObject.put(Common.TYPE, Article.ARTICLE);
fillCommenter(requestJSONObject, httpServletRequest);
final JSONObject jsonObject = commentMgmtService.checkAddCommentRequest(requestJSONObject); final JSONObject jsonObject = commentMgmtService.checkAddCommentRequest(requestJSONObject);
final JSONRenderer renderer = new JSONRenderer(); final JSONRenderer renderer = new JSONRenderer();
...@@ -229,9 +235,9 @@ public class CommentProcessor { ...@@ -229,9 +235,9 @@ public class CommentProcessor {
final String storedCaptcha = (String) session.getAttribute(CaptchaProcessor.CAPTCHA); final String storedCaptcha = (String) session.getAttribute(CaptchaProcessor.CAPTCHA);
session.removeAttribute(CaptchaProcessor.CAPTCHA); session.removeAttribute(CaptchaProcessor.CAPTCHA);
if (!userQueryService.isLoggedIn(httpServletRequest, httpServletResponse)) { if (!userQueryService.isLoggedIn(httpServletRequest, httpServletResponse)) {
final String captcha = requestJSONObject.optString(CaptchaProcessor.CAPTCHA); final String captcha = requestJSONObject.optString(CaptchaProcessor.CAPTCHA);
if (null == storedCaptcha || !storedCaptcha.equals(captcha)) { if (null == storedCaptcha || !storedCaptcha.equals(captcha)) {
...@@ -255,4 +261,22 @@ public class CommentProcessor { ...@@ -255,4 +261,22 @@ public class CommentProcessor {
jsonObject.put(Keys.MSG, langPropsService.get("addFailLabel")); jsonObject.put(Keys.MSG, langPropsService.get("addFailLabel"));
} }
} }
/**
* Fills commenter info if logged in.
*
* @param requestJSONObject the specified request json object
* @param httpServletRequest the specified HTTP servlet request
*/
private void fillCommenter(final JSONObject requestJSONObject, final HttpServletRequest httpServletRequest) {
final JSONObject currentUser = userQueryService.getCurrentUser(httpServletRequest);
if (null == currentUser) {
return;
}
requestJSONObject.put(Comment.COMMENT_NAME, currentUser.optString(User.USER_NAME));
requestJSONObject.put(Comment.COMMENT_EMAIL, currentUser.optString(User.USER_EMAIL));
requestJSONObject.put(Comment.COMMENT_URL, currentUser.optString(User.USER_URL));
}
} }
...@@ -108,7 +108,7 @@ public class ErrorProcessor { ...@@ -108,7 +108,7 @@ public class ErrorProcessor {
dataModel.putAll(langs); dataModel.putAll(langs);
final JSONObject preference = preferenceQueryService.getPreference(); final JSONObject preference = preferenceQueryService.getPreference();
filler.fillBlogHeader(request, dataModel, preference); filler.fillBlogHeader(request, response, dataModel, preference);
filler.fillBlogFooter(request, dataModel, preference); filler.fillBlogFooter(request, dataModel, preference);
dataModel.put(Common.LOGIN_URL, userService.createLoginURL(Common.ADMIN_INDEX_URI)); dataModel.put(Common.LOGIN_URL, userService.createLoginURL(Common.ADMIN_INDEX_URI));
......
...@@ -59,7 +59,6 @@ import org.b3log.solo.repository.TagRepository; ...@@ -59,7 +59,6 @@ import org.b3log.solo.repository.TagRepository;
import org.b3log.solo.service.ArticleQueryService; import org.b3log.solo.service.ArticleQueryService;
import org.b3log.solo.service.PreferenceQueryService; import org.b3log.solo.service.PreferenceQueryService;
import org.b3log.solo.service.UserQueryService; import org.b3log.solo.service.UserQueryService;
import org.b3log.solo.util.TimeZones;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
...@@ -137,7 +136,7 @@ public class FeedProcessor { ...@@ -137,7 +136,7 @@ public class FeedProcessor {
feed.setTitle(StringEscapeUtils.escapeXml(blogTitle)); feed.setTitle(StringEscapeUtils.escapeXml(blogTitle));
feed.setSubtitle(StringEscapeUtils.escapeXml(blogSubtitle)); feed.setSubtitle(StringEscapeUtils.escapeXml(blogSubtitle));
feed.setUpdated(TimeZones.getTime(preference.getString(Preference.TIME_ZONE_ID))); feed.setUpdated(new Date());
feed.setAuthor(StringEscapeUtils.escapeXml(blogTitle)); feed.setAuthor(StringEscapeUtils.escapeXml(blogTitle));
feed.setLink(Latkes.getServePath() + "/blog-articles-feed.do"); feed.setLink(Latkes.getServePath() + "/blog-articles-feed.do");
feed.setId(Latkes.getServePath() + "/"); feed.setId(Latkes.getServePath() + "/");
...@@ -263,7 +262,7 @@ public class FeedProcessor { ...@@ -263,7 +262,7 @@ public class FeedProcessor {
feed.setTitle(StringEscapeUtils.escapeXml(blogTitle)); feed.setTitle(StringEscapeUtils.escapeXml(blogTitle));
feed.setSubtitle(StringEscapeUtils.escapeXml(blogSubtitle)); feed.setSubtitle(StringEscapeUtils.escapeXml(blogSubtitle));
feed.setUpdated(TimeZones.getTime(preference.getString(Preference.TIME_ZONE_ID))); feed.setUpdated(new Date());
feed.setAuthor(StringEscapeUtils.escapeXml(blogTitle)); feed.setAuthor(StringEscapeUtils.escapeXml(blogTitle));
feed.setLink(Latkes.getServePath() + "/tag-articles-feed.do"); feed.setLink(Latkes.getServePath() + "/tag-articles-feed.do");
feed.setId(Latkes.getServePath() + "/"); feed.setId(Latkes.getServePath() + "/");
...@@ -375,7 +374,7 @@ public class FeedProcessor { ...@@ -375,7 +374,7 @@ public class FeedProcessor {
final int outputCnt = preference.getInt(Preference.FEED_OUTPUT_CNT); final int outputCnt = preference.getInt(Preference.FEED_OUTPUT_CNT);
channel.setTitle(StringEscapeUtils.escapeXml(blogTitle)); channel.setTitle(StringEscapeUtils.escapeXml(blogTitle));
channel.setLastBuildDate(TimeZones.getTime(preference.getString(Preference.TIME_ZONE_ID))); channel.setLastBuildDate(new Date());
channel.setLink(Latkes.getServePath()); channel.setLink(Latkes.getServePath());
channel.setAtomLink(Latkes.getServePath() + "/blog-articles-rss.do"); channel.setAtomLink(Latkes.getServePath() + "/blog-articles-rss.do");
channel.setGenerator("B3log Solo, ver " + SoloServletListener.VERSION); channel.setGenerator("B3log Solo, ver " + SoloServletListener.VERSION);
...@@ -508,7 +507,7 @@ public class FeedProcessor { ...@@ -508,7 +507,7 @@ public class FeedProcessor {
final int outputCnt = preference.getInt(Preference.FEED_OUTPUT_CNT); final int outputCnt = preference.getInt(Preference.FEED_OUTPUT_CNT);
channel.setTitle(StringEscapeUtils.escapeXml(blogTitle)); channel.setTitle(StringEscapeUtils.escapeXml(blogTitle));
channel.setLastBuildDate(TimeZones.getTime(preference.getString(Preference.TIME_ZONE_ID))); channel.setLastBuildDate(new Date());
channel.setLink(Latkes.getServePath()); channel.setLink(Latkes.getServePath());
channel.setAtomLink(Latkes.getServePath() + "/tag-articles-rss.do"); channel.setAtomLink(Latkes.getServePath() + "/tag-articles-rss.do");
channel.setGenerator("B3log Solo, ver " + SoloServletListener.VERSION); channel.setGenerator("B3log Solo, ver " + SoloServletListener.VERSION);
......
...@@ -26,7 +26,6 @@ import javax.servlet.http.HttpServletRequest; ...@@ -26,7 +26,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.model.Pagination; import org.b3log.latke.model.Pagination;
...@@ -38,13 +37,12 @@ import org.b3log.latke.servlet.URIPatternMode; ...@@ -38,13 +37,12 @@ import org.b3log.latke.servlet.URIPatternMode;
import org.b3log.latke.servlet.annotation.RequestProcessing; import org.b3log.latke.servlet.annotation.RequestProcessing;
import org.b3log.latke.servlet.annotation.RequestProcessor; import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer; import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer;
import org.b3log.latke.servlet.renderer.freemarker.FreeMarkerRenderer;
import org.b3log.latke.util.Locales; import org.b3log.latke.util.Locales;
import org.b3log.latke.util.Requests; import org.b3log.latke.util.Requests;
import org.b3log.solo.model.Common; import org.b3log.solo.model.Common;
import org.b3log.solo.model.PageTypes;
import org.b3log.solo.model.Preference; import org.b3log.solo.model.Preference;
import org.b3log.solo.processor.renderer.ConsoleRenderer; import org.b3log.solo.processor.renderer.ConsoleRenderer;
import org.b3log.solo.processor.renderer.FrontRenderer;
import org.b3log.solo.processor.util.Filler; import org.b3log.solo.processor.util.Filler;
import org.b3log.solo.service.PreferenceQueryService; import org.b3log.solo.service.PreferenceQueryService;
import org.b3log.solo.util.Skins; import org.b3log.solo.util.Skins;
...@@ -56,7 +54,7 @@ import org.json.JSONObject; ...@@ -56,7 +54,7 @@ import org.json.JSONObject;
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="mailto:385321165@qq.com">DASHU</a> * @author <a href="mailto:385321165@qq.com">DASHU</a>
* @version 1.1.1.3, Jul 11, 2013 * @version 1.1.1.4, Sep 11, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
@RequestProcessor @RequestProcessor
...@@ -94,7 +92,7 @@ public class IndexProcessor { ...@@ -94,7 +92,7 @@ public class IndexProcessor {
*/ */
@RequestProcessing(value = { "/\\d*", ""}, uriPatternsMode = URIPatternMode.REGEX, method = HTTPRequestMethod.GET) @RequestProcessing(value = { "/\\d*", ""}, uriPatternsMode = URIPatternMode.REGEX, method = HTTPRequestMethod.GET)
public void showIndex(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) { public void showIndex(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) {
final AbstractFreeMarkerRenderer renderer = new FrontRenderer(); final AbstractFreeMarkerRenderer renderer = new FreeMarkerRenderer();
context.setRenderer(renderer); context.setRenderer(renderer);
...@@ -109,18 +107,10 @@ public class IndexProcessor { ...@@ -109,18 +107,10 @@ public class IndexProcessor {
Skins.fillLangs(preference.optString(Preference.LOCALE_STRING), (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), dataModel); Skins.fillLangs(preference.optString(Preference.LOCALE_STRING), (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), dataModel);
request.setAttribute(PageCaches.CACHED_OID, "No id");
request.setAttribute(PageCaches.CACHED_TITLE,
langPropsService.get(PageTypes.INDEX.getLangeLabel()) + " [" + langPropsService.get("pageNumLabel") + "=" + currentPageNum
+ "]");
request.setAttribute(PageCaches.CACHED_TYPE, langPropsService.get(PageTypes.INDEX.getLangeLabel()));
request.setAttribute(PageCaches.CACHED_LINK, requestURI);
filler.fillIndexArticles(request, dataModel, currentPageNum, preference); filler.fillIndexArticles(request, dataModel, currentPageNum, preference);
dataModel.put(Keys.PAGE_TYPE, PageTypes.INDEX);
filler.fillSide(request, dataModel, preference); filler.fillSide(request, dataModel, preference);
filler.fillBlogHeader(request, dataModel, preference); filler.fillBlogHeader(request, response, dataModel, preference);
filler.fillBlogFooter(request, dataModel, preference); filler.fillBlogFooter(request, dataModel, preference);
dataModel.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, currentPageNum); dataModel.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, currentPageNum);
...@@ -171,13 +161,6 @@ public class IndexProcessor { ...@@ -171,13 +161,6 @@ public class IndexProcessor {
filler.fillBlogFooter(request, dataModel, preference); filler.fillBlogFooter(request, dataModel, preference);
Keys.fillRuntime(dataModel); Keys.fillRuntime(dataModel);
filler.fillMinified(dataModel); filler.fillMinified(dataModel);
dataModel.put(Keys.PAGE_TYPE, PageTypes.KILL_BROWSER);
request.setAttribute(PageCaches.CACHED_OID, "No id");
request.setAttribute(PageCaches.CACHED_TITLE, "Kill Browser Page");
request.setAttribute(PageCaches.CACHED_TYPE, langs.get(PageTypes.KILL_BROWSER.getLangeLabel()));
request.setAttribute(PageCaches.CACHED_LINK, request.getRequestURI());
} catch (final ServiceException e) { } catch (final ServiceException e) {
LOGGER.log(Level.ERROR, e.getMessage(), e); LOGGER.log(Level.ERROR, e.getMessage(), e);
...@@ -234,7 +217,7 @@ public class IndexProcessor { ...@@ -234,7 +217,7 @@ public class IndexProcessor {
* can not convert to an number * can not convert to an number
*/ */
private static int getCurrentPageNum(final String requestURI) { private static int getCurrentPageNum(final String requestURI) {
final String pageNumString = StringUtils.substringAfter(requestURI, "/"); final String pageNumString = StringUtils.substringAfterLast(requestURI, "/");
return Requests.getCurrentPageNum(pageNumString); return Requests.getCurrentPageNum(pageNumString);
} }
...@@ -272,8 +255,6 @@ public class IndexProcessor { ...@@ -272,8 +255,6 @@ public class IndexProcessor {
final String pageContent = stringWriter.toString(); final String pageContent = stringWriter.toString();
context.getRequest().setAttribute(PageCaches.CACHED_CONTENT, pageContent);
writer.write(pageContent); writer.write(pageContent);
writer.flush(); writer.flush();
writer.close(); writer.close();
......
...@@ -68,7 +68,7 @@ import java.util.Map; ...@@ -68,7 +68,7 @@ import java.util.Map;
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="mailto:LLY219@gmail.com">Liyuan Li</a> * @author <a href="mailto:LLY219@gmail.com">Liyuan Li</a>
* @author <a href="mailto:dongxu.wang@acm.org">Dongxu Wang</a> * @author <a href="mailto:dongxu.wang@acm.org">Dongxu Wang</a>
* @version 1.1.1.5, Jul 4, 2013 * @version 1.1.1.6, Oct 26, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
@RequestProcessor @RequestProcessor
...@@ -162,23 +162,26 @@ public class LoginProcessor { ...@@ -162,23 +162,26 @@ public class LoginProcessor {
return; return;
} }
renderPage(context, "login.ftl", destinationURL, request); renderPage(context, "login.ftl", destinationURL, request);
} }
/** /**
* Logins. * Logins.
* <p/> *
* <p> Renders the response with a json object, for example, * <p>
* Renders the response with a json object, for example,
* <pre> * <pre>
* { * {
* "isLoggedIn": boolean, * "isLoggedIn": boolean,
* "msg": "" // optional, exists if isLoggedIn equals to false * "msg": "" // optional, exists if isLoggedIn equals to false
* } * }
* </pre> </p> * </pre>
* </p>
* *
* @param context the specified context * @param context the specified context
*/ */
@RequestProcessing(value = { "/login"}, method = HTTPRequestMethod.POST) @RequestProcessing(value = "/login", method = HTTPRequestMethod.POST)
public void login(final HTTPRequestContext context) { public void login(final HTTPRequestContext context) {
final HttpServletRequest request = context.getRequest(); final HttpServletRequest request = context.getRequest();
...@@ -242,7 +245,7 @@ public class LoginProcessor { ...@@ -242,7 +245,7 @@ public class LoginProcessor {
* @param context the specified context * @param context the specified context
* @throws IOException io exception * @throws IOException io exception
*/ */
@RequestProcessing(value = { "/logout"}, method = HTTPRequestMethod.GET) @RequestProcessing(value = "/logout", method = HTTPRequestMethod.GET)
public void logout(final HTTPRequestContext context) throws IOException { public void logout(final HTTPRequestContext context) throws IOException {
final HttpServletRequest httpServletRequest = context.getRequest(); final HttpServletRequest httpServletRequest = context.getRequest();
...@@ -277,19 +280,21 @@ public class LoginProcessor { ...@@ -277,19 +280,21 @@ public class LoginProcessor {
} }
/** /**
* reset forgotten password. * Resets forgotten password.
* <p/> *
* <p> Renders the response with a json object, for example, * <p>
* Renders the response with a json object, for example,
* <pre> * <pre>
* { * {
* "isLoggedIn": boolean, * "isLoggedIn": boolean,
* "msg": "" // optional, exists if isLoggedIn equals to false * "msg": "" // optional, exists if isLoggedIn equals to false
* } * }
* </pre> </p> * </pre>
* </p>
* *
* @param context the specified context * @param context the specified context
*/ */
@RequestProcessing(value = { "/forgot"}, method = HTTPRequestMethod.POST) @RequestProcessing(value = "/forgot", method = HTTPRequestMethod.POST)
public void forgot(final HTTPRequestContext context) { public void forgot(final HTTPRequestContext context) {
final HttpServletRequest request = context.getRequest(); final HttpServletRequest request = context.getRequest();
...@@ -329,19 +334,21 @@ public class LoginProcessor { ...@@ -329,19 +334,21 @@ public class LoginProcessor {
} }
/** /**
* reset forgotten password. * Resets forgotten password.
* <p/> *
* <p> Renders the response with a json object, for example, * <p>
* Renders the response with a json object, for example,
* <pre> * <pre>
* { * {
* "isLoggedIn": boolean, * "isLoggedIn": boolean,
* "msg": "" // optional, exists if isLoggedIn equals to false * "msg": "" // optional, exists if isLoggedIn equals to false
* } * }
* </pre> </p> * </pre>
* </p>
* *
* @param context the specified context * @param context the specified context
*/ */
@RequestProcessing(value = { "/reset"}, method = HTTPRequestMethod.POST) @RequestProcessing(value = "/reset", method = HTTPRequestMethod.POST)
public void reset(final HTTPRequestContext context) { public void reset(final HTTPRequestContext context) {
final HttpServletRequest request = context.getRequest(); final HttpServletRequest request = context.getRequest();
final JSONRenderer renderer = new JSONRenderer(); final JSONRenderer renderer = new JSONRenderer();
...@@ -381,7 +388,7 @@ public class LoginProcessor { ...@@ -381,7 +388,7 @@ public class LoginProcessor {
} }
/** /**
* Send the password resetting URL with a random token. * Sends the password resetting URL with a random token.
* *
* @param userEmail the given email * @param userEmail the given email
* @param jsonObject return code and message object * @param jsonObject return code and message object
...@@ -394,7 +401,6 @@ public class LoginProcessor { ...@@ -394,7 +401,6 @@ public class LoginProcessor {
ServiceException, IOException, RepositoryException { ServiceException, IOException, RepositoryException {
final JSONObject preference = preferenceQueryService.getPreference(); final JSONObject preference = preferenceQueryService.getPreference();
final String token = new Randoms().nextStringWithMD5(); final String token = new Randoms().nextStringWithMD5();
final String blogTitle = preference.getString(Preference.BLOG_TITLE);
final String adminEmail = preference.getString(Preference.ADMIN_EMAIL); final String adminEmail = preference.getString(Preference.ADMIN_EMAIL);
final String mailSubject = langPropsService.get("resetPwdMailSubject"); final String mailSubject = langPropsService.get("resetPwdMailSubject");
final String mailBody = langPropsService.get("resetPwdMailBody") + " " + Latkes.getServePath() + "/forgot?token=" + token final String mailBody = langPropsService.get("resetPwdMailBody") + " " + Latkes.getServePath() + "/forgot?token=" + token
...@@ -423,7 +429,7 @@ public class LoginProcessor { ...@@ -423,7 +429,7 @@ public class LoginProcessor {
jsonObject.put("to", Latkes.getServePath() + "/login?from=forgot"); jsonObject.put("to", Latkes.getServePath() + "/login?from=forgot");
jsonObject.put(Keys.MSG, langPropsService.get("resetPwdSuccessSend")); jsonObject.put(Keys.MSG, langPropsService.get("resetPwdSuccessSend"));
LOGGER.log(Level.DEBUG, "Sending a mail[mailSubject={0}, mailBody=[{1}] to [{2}]", new Object[] {mailSubject, mailBody, userEmail}); LOGGER.log(Level.DEBUG, "Sent a mail[mailSubject={0}, mailBody=[{1}] to [{2}]", new Object[] {mailSubject, mailBody, userEmail});
} }
/** /**
...@@ -436,8 +442,8 @@ public class LoginProcessor { ...@@ -436,8 +442,8 @@ public class LoginProcessor {
* @throws JSONException the JSONException * @throws JSONException the JSONException
* @throws ServiceException the ServiceException * @throws ServiceException the ServiceException
*/ */
private void renderPage(final HTTPRequestContext context, final String pageTemplate, final String destinationURL, final HttpServletRequest request) throws JSONException, private void renderPage(final HTTPRequestContext context, final String pageTemplate, final String destinationURL,
ServiceException { final HttpServletRequest request) throws JSONException, ServiceException {
final AbstractFreeMarkerRenderer renderer = new ConsoleRenderer(); final AbstractFreeMarkerRenderer renderer = new ConsoleRenderer();
renderer.setTemplateName(pageTemplate); renderer.setTemplateName(pageTemplate);
......
...@@ -24,7 +24,6 @@ import javax.servlet.http.HttpServletRequest; ...@@ -24,7 +24,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.Latkes; import org.b3log.latke.Latkes;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.service.LangPropsService; import org.b3log.latke.service.LangPropsService;
...@@ -33,12 +32,11 @@ import org.b3log.latke.servlet.HTTPRequestMethod; ...@@ -33,12 +32,11 @@ import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.annotation.RequestProcessing; import org.b3log.latke.servlet.annotation.RequestProcessing;
import org.b3log.latke.servlet.annotation.RequestProcessor; import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer; import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer;
import org.b3log.latke.servlet.renderer.freemarker.FreeMarkerRenderer;
import org.b3log.latke.util.Stopwatchs; import org.b3log.latke.util.Stopwatchs;
import org.b3log.solo.model.Common; import org.b3log.solo.model.Common;
import org.b3log.solo.model.Page; import org.b3log.solo.model.Page;
import org.b3log.solo.model.PageTypes;
import org.b3log.solo.model.Preference; import org.b3log.solo.model.Preference;
import org.b3log.solo.processor.renderer.FrontRenderer;
import org.b3log.solo.processor.util.Filler; import org.b3log.solo.processor.util.Filler;
import org.b3log.solo.service.CommentQueryService; import org.b3log.solo.service.CommentQueryService;
import org.b3log.solo.service.PreferenceQueryService; import org.b3log.solo.service.PreferenceQueryService;
...@@ -51,7 +49,7 @@ import org.json.JSONObject; ...@@ -51,7 +49,7 @@ import org.json.JSONObject;
* Page processor. * Page processor.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.2, Apr 29, 2012 * @version 1.1.0.3, Oct 14, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
@RequestProcessor @RequestProcessor
...@@ -93,7 +91,7 @@ public class PageProcessor { ...@@ -93,7 +91,7 @@ public class PageProcessor {
*/ */
@RequestProcessing(value = "/page", method = HTTPRequestMethod.GET) @RequestProcessing(value = "/page", method = HTTPRequestMethod.GET)
public void showPage(final HTTPRequestContext context) { public void showPage(final HTTPRequestContext context) {
final AbstractFreeMarkerRenderer renderer = new FrontRenderer(); final AbstractFreeMarkerRenderer renderer = new FreeMarkerRenderer();
context.setRenderer(renderer); context.setRenderer(renderer);
...@@ -115,8 +113,6 @@ public class PageProcessor { ...@@ -115,8 +113,6 @@ public class PageProcessor {
final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale()); final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale());
request.setAttribute(PageCaches.CACHED_TYPE, langs.get(PageTypes.PAGE.getLangeLabel()));
// See PermalinkFiler#dispatchToArticleOrPageProcessor() // See PermalinkFiler#dispatchToArticleOrPageProcessor()
final JSONObject page = (JSONObject) request.getAttribute(Page.PAGE); final JSONObject page = (JSONObject) request.getAttribute(Page.PAGE);
...@@ -127,11 +123,7 @@ public class PageProcessor { ...@@ -127,11 +123,7 @@ public class PageProcessor {
final String pageId = page.getString(Keys.OBJECT_ID); final String pageId = page.getString(Keys.OBJECT_ID);
request.setAttribute(PageCaches.CACHED_OID, pageId); page.put(Common.COMMENTABLE, preference.getBoolean(Preference.COMMENTABLE) && page.getBoolean(Page.PAGE_COMMENTABLE));
request.setAttribute(PageCaches.CACHED_TITLE, page.getString(Page.PAGE_TITLE));
request.setAttribute(PageCaches.CACHED_LINK, page.getString(Page.PAGE_PERMALINK));
page.put(Common.COMMENTABLE, page.getBoolean(Page.PAGE_COMMENTABLE));
page.put(Common.PERMALINK, page.getString(Page.PAGE_PERMALINK)); page.put(Common.PERMALINK, page.getString(Page.PAGE_PERMALINK));
dataModel.put(Page.PAGE, page); dataModel.put(Page.PAGE, page);
final List<JSONObject> comments = commentQueryService.getComments(pageId); final List<JSONObject> comments = commentQueryService.getComments(pageId);
...@@ -149,9 +141,8 @@ public class PageProcessor { ...@@ -149,9 +141,8 @@ public class PageProcessor {
Stopwatchs.end(); Stopwatchs.end();
} }
dataModel.put(Keys.PAGE_TYPE, PageTypes.PAGE);
filler.fillSide(request, dataModel, preference); filler.fillSide(request, dataModel, preference);
filler.fillBlogHeader(request, dataModel, preference); filler.fillBlogHeader(request, response, dataModel, preference);
filler.fillBlogFooter(request, dataModel, preference); filler.fillBlogFooter(request, dataModel, preference);
} catch (final Exception e) { } catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e); LOGGER.log(Level.ERROR, e.getMessage(), e);
......
...@@ -25,7 +25,6 @@ import javax.servlet.http.HttpServletRequest; ...@@ -25,7 +25,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.Latkes; import org.b3log.latke.Latkes;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.ioc.LatkeBeanManager; import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
...@@ -33,6 +32,7 @@ import org.b3log.latke.mail.MailService; ...@@ -33,6 +32,7 @@ import org.b3log.latke.mail.MailService;
import org.b3log.latke.mail.MailService.Message; import org.b3log.latke.mail.MailService.Message;
import org.b3log.latke.mail.MailServiceFactory; import org.b3log.latke.mail.MailServiceFactory;
import org.b3log.latke.repository.*; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.annotation.Transactional;
import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestMethod; import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.annotation.RequestProcessing; import org.b3log.latke.servlet.annotation.RequestProcessing;
...@@ -69,7 +69,7 @@ import org.json.JSONObject; ...@@ -69,7 +69,7 @@ import org.json.JSONObject;
* <p>See AuthFilter filter configurations in web.xml for authentication.</p> * <p>See AuthFilter filter configurations in web.xml for authentication.</p>
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.8, Dec 25, 2012 * @version 1.1.0.10, Oct 26, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
@RequestProcessor @RequestProcessor
...@@ -209,8 +209,6 @@ public class RepairProcessor { ...@@ -209,8 +209,6 @@ public class RepairProcessor {
context.setRenderer(renderer); context.setRenderer(renderer);
try { try {
PageCaches.removeAll(); // Clears all first
final JSONObject statistic = statisticQueryService.getStatistic(); final JSONObject statistic = statisticQueryService.getStatistic();
if (statistic.has(Statistic.STATISTIC_BLOG_COMMENT_COUNT) && statistic.has(Statistic.STATISTIC_BLOG_ARTICLE_COUNT)) { if (statistic.has(Statistic.STATISTIC_BLOG_COMMENT_COUNT) && statistic.has(Statistic.STATISTIC_BLOG_ARTICLE_COUNT)) {
...@@ -278,13 +276,12 @@ public class RepairProcessor { ...@@ -278,13 +276,12 @@ public class RepairProcessor {
* @param context the specified context * @param context the specified context
*/ */
@RequestProcessing(value = "/fix/tag-article-counter-repair.do", method = HTTPRequestMethod.GET) @RequestProcessing(value = "/fix/tag-article-counter-repair.do", method = HTTPRequestMethod.GET)
@Transactional
public void repairTagArticleCounter(final HTTPRequestContext context) { public void repairTagArticleCounter(final HTTPRequestContext context) {
final TextHTMLRenderer renderer = new TextHTMLRenderer(); final TextHTMLRenderer renderer = new TextHTMLRenderer();
context.setRenderer(renderer); context.setRenderer(renderer);
final Transaction transaction = tagRepository.beginTransaction();
try { try {
final JSONObject result = tagRepository.get(new Query()); final JSONObject result = tagRepository.get(new Query());
final JSONArray tagArray = result.getJSONArray(Keys.RESULTS); final JSONArray tagArray = result.getJSONArray(Keys.RESULTS);
...@@ -301,9 +298,14 @@ public class RepairProcessor { ...@@ -301,9 +298,14 @@ public class RepairProcessor {
final JSONObject tagArticle = tagArticles.getJSONObject(i); final JSONObject tagArticle = tagArticles.getJSONObject(i);
final String articleId = tagArticle.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID); final String articleId = tagArticle.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID);
final JSONObject article = articleRepository.get(articleId); final JSONObject article = articleRepository.get(articleId);
final boolean isPublished = article.getBoolean(Article.ARTICLE_IS_PUBLISHED);
if (isPublished) { if (null == article) {
tagArticleRepository.remove(tagArticle.optString(Keys.OBJECT_ID));
continue;
}
if (article.getBoolean(Article.ARTICLE_IS_PUBLISHED)) {
publishedTagRefCnt++; publishedTagRefCnt++;
} }
} }
...@@ -317,14 +319,8 @@ public class RepairProcessor { ...@@ -317,14 +319,8 @@ public class RepairProcessor {
new Object[] {tag.getString(Tag.TAG_TITLE), tagRefCnt, publishedTagRefCnt}); new Object[] {tag.getString(Tag.TAG_TITLE), tagRefCnt, publishedTagRefCnt});
} }
transaction.commit();
renderer.setContent("Repair sucessfully!"); renderer.setContent("Repair sucessfully!");
} catch (final Exception e) { } catch (final Exception e) {
if (transaction.isActive()) {
transaction.rollback();
}
LOGGER.log(Level.ERROR, e.getMessage(), e); LOGGER.log(Level.ERROR, e.getMessage(), e);
renderer.setContent("Repairs failed, error msg[" + e.getMessage() + "]"); renderer.setContent("Repairs failed, error msg[" + e.getMessage() + "]");
} }
...@@ -347,7 +343,7 @@ public class RepairProcessor { ...@@ -347,7 +343,7 @@ public class RepairProcessor {
htmlBuilder.append("<html><head><title>WARNING!</title>"); htmlBuilder.append("<html><head><title>WARNING!</title>");
htmlBuilder.append("<script type='text/javascript'"); htmlBuilder.append("<script type='text/javascript'");
htmlBuilder.append("src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js'"); htmlBuilder.append("src='").append(Latkes.getStaticServer()).append("/js/lib/jquery/jquery.min.js'");
htmlBuilder.append("></script></head><body>"); htmlBuilder.append("></script></head><body>");
htmlBuilder.append("<button id='ok' onclick='removeData()'>"); htmlBuilder.append("<button id='ok' onclick='removeData()'>");
htmlBuilder.append("Continue to delete ALL DATA</button></body>"); htmlBuilder.append("Continue to delete ALL DATA</button></body>");
...@@ -378,8 +374,6 @@ public class RepairProcessor { ...@@ -378,8 +374,6 @@ public class RepairProcessor {
public void removeAllDataPOST(final HTTPRequestContext context) { public void removeAllDataPOST(final HTTPRequestContext context) {
LOGGER.info("Removing all data...."); LOGGER.info("Removing all data....");
PageCaches.removeAll();
boolean succeed = false; boolean succeed = false;
try { try {
......
...@@ -141,13 +141,9 @@ public class SitemapProcessor { ...@@ -141,13 +141,9 @@ public class SitemapProcessor {
final Query query = new Query().setCurrentPageNum(1).setFilter(new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true)).addSort( final Query query = new Query().setCurrentPageNum(1).setFilter(new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true)).addSort(
Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING); Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING);
// Closes cache avoid Java heap space out of memory while caching query results // XXX: maybe out of memory
articleRepository.setCacheEnabled(false);
final JSONObject articleResult = articleRepository.get(query); final JSONObject articleResult = articleRepository.get(query);
articleRepository.setCacheEnabled(true); // Restores cache
final JSONArray articles = articleResult.getJSONArray(Keys.RESULTS); final JSONArray articles = articleResult.getJSONArray(Keys.RESULTS);
for (int i = 0; i < articles.length(); i++) { for (int i = 0; i < articles.length(); i++) {
......
...@@ -17,9 +17,7 @@ package org.b3log.solo.processor; ...@@ -17,9 +17,7 @@ package org.b3log.solo.processor;
import javax.inject.Inject; import javax.inject.Inject;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.service.ServiceException;
import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestMethod; import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.annotation.RequestProcessing; import org.b3log.latke.servlet.annotation.RequestProcessing;
...@@ -40,7 +38,7 @@ import org.b3log.solo.service.StatisticMgmtService; ...@@ -40,7 +38,7 @@ import org.b3log.solo.service.StatisticMgmtService;
* <p> * <p>
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.1.9, Mar 6, 2013 * @version 1.0.2.0, Oct 12, 2013
* @since 0.4.0 * @since 0.4.0
*/ */
@RequestProcessor @RequestProcessor
...@@ -68,22 +66,4 @@ public class StatProcessor { ...@@ -68,22 +66,4 @@ public class StatProcessor {
statisticMgmtService.removeExpiredOnlineVisitor(); statisticMgmtService.removeExpiredOnlineVisitor();
} }
/**
* Increments Blog/Articles view counter.
*
* @param context the specified context
*/
@RequestProcessing(value = "/console/stat/viewcnt", method = HTTPRequestMethod.GET)
public void viewCounter(final HTTPRequestContext context) {
LOGGER.log(Level.INFO, "Sync statistic from memcache to repository");
context.setRenderer(new DoNothingRenderer());
try {
statisticMgmtService.flushStatistic();
} catch (final ServiceException e) {
LOGGER.log(Level.ERROR, "Flushes statistic to repository failed", e);
}
}
} }
...@@ -27,7 +27,6 @@ import javax.servlet.http.HttpServletRequest; ...@@ -27,7 +27,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.Latkes; import org.b3log.latke.Latkes;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.model.Pagination; import org.b3log.latke.model.Pagination;
...@@ -38,15 +37,14 @@ import org.b3log.latke.servlet.HTTPRequestMethod; ...@@ -38,15 +37,14 @@ import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.annotation.RequestProcessing; import org.b3log.latke.servlet.annotation.RequestProcessing;
import org.b3log.latke.servlet.annotation.RequestProcessor; import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer; import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer;
import org.b3log.latke.servlet.renderer.freemarker.FreeMarkerRenderer;
import org.b3log.latke.util.Paginator; import org.b3log.latke.util.Paginator;
import org.b3log.latke.util.Requests; import org.b3log.latke.util.Requests;
import org.b3log.latke.util.Strings; import org.b3log.latke.util.Strings;
import org.b3log.solo.model.Article; import org.b3log.solo.model.Article;
import org.b3log.solo.model.Common; import org.b3log.solo.model.Common;
import org.b3log.solo.model.PageTypes;
import org.b3log.solo.model.Preference; import org.b3log.solo.model.Preference;
import org.b3log.solo.model.Tag; import org.b3log.solo.model.Tag;
import org.b3log.solo.processor.renderer.FrontRenderer;
import org.b3log.solo.processor.util.Filler; import org.b3log.solo.processor.util.Filler;
import org.b3log.solo.service.ArticleQueryService; import org.b3log.solo.service.ArticleQueryService;
import org.b3log.solo.service.PreferenceQueryService; import org.b3log.solo.service.PreferenceQueryService;
...@@ -62,7 +60,7 @@ import org.json.JSONObject; ...@@ -62,7 +60,7 @@ import org.json.JSONObject;
* Tag processor. * Tag processor.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.1.1, Jul 11, 2013 * @version 1.1.1.2, Oct 29, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
@RequestProcessor @RequestProcessor
...@@ -111,13 +109,13 @@ public class TagProcessor { ...@@ -111,13 +109,13 @@ public class TagProcessor {
/** /**
* Shows articles related with a tag with the specified context. * Shows articles related with a tag with the specified context.
* *
* @param context the specified context * @param context the specified context
* @throws IOException io exception * @throws IOException io exception
*/ */
@RequestProcessing(value = "/tags/**", method = HTTPRequestMethod.GET) @RequestProcessing(value = "/tags/**", method = HTTPRequestMethod.GET)
public void showTagArticles(final HTTPRequestContext context) throws IOException { public void showTagArticles(final HTTPRequestContext context) throws IOException {
final AbstractFreeMarkerRenderer renderer = new FrontRenderer(); final AbstractFreeMarkerRenderer renderer = new FreeMarkerRenderer();
context.setRenderer(renderer); context.setRenderer(renderer);
...@@ -162,16 +160,6 @@ public class TagProcessor { ...@@ -162,16 +160,6 @@ public class TagProcessor {
final int pageSize = preference.getInt(Preference.ARTICLE_LIST_DISPLAY_COUNT); final int pageSize = preference.getInt(Preference.ARTICLE_LIST_DISPLAY_COUNT);
final int windowSize = preference.getInt(Preference.ARTICLE_LIST_PAGINATION_WINDOW_SIZE); final int windowSize = preference.getInt(Preference.ARTICLE_LIST_PAGINATION_WINDOW_SIZE);
request.setAttribute(PageCaches.CACHED_OID, tagId);
final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale());
request.setAttribute(PageCaches.CACHED_TITLE,
langs.get(PageTypes.TAG_ARTICLES.getLangeLabel()) + " [" + langs.get("pageNumLabel") + "=" + currentPageNum + ", "
+ langs.get("tagLabel") + "=" + tagTitle + "]");
request.setAttribute(PageCaches.CACHED_TYPE, langs.get(PageTypes.TAG_ARTICLES.getLangeLabel()));
request.setAttribute(PageCaches.CACHED_LINK, requestURI);
final List<JSONObject> articles = articleQueryService.getArticlesByTag(tagId, currentPageNum, pageSize); final List<JSONObject> articles = articleQueryService.getArticlesByTag(tagId, currentPageNum, pageSize);
if (articles.isEmpty()) { if (articles.isEmpty()) {
...@@ -210,9 +198,8 @@ public class TagProcessor { ...@@ -210,9 +198,8 @@ public class TagProcessor {
dataModel.put(Keys.OBJECT_ID, tagId); dataModel.put(Keys.OBJECT_ID, tagId);
dataModel.put(Tag.TAG, tag); dataModel.put(Tag.TAG, tag);
dataModel.put(Keys.PAGE_TYPE, PageTypes.TAG_ARTICLES);
filler.fillSide(request, dataModel, preference); filler.fillSide(request, dataModel, preference);
filler.fillBlogHeader(request, dataModel, preference); filler.fillBlogHeader(request, response, dataModel, preference);
filler.fillBlogFooter(request, dataModel, preference); filler.fillBlogFooter(request, dataModel, preference);
} catch (final ServiceException e) { } catch (final ServiceException e) {
LOGGER.log(Level.ERROR, e.getMessage(), e); LOGGER.log(Level.ERROR, e.getMessage(), e);
...@@ -235,7 +222,7 @@ public class TagProcessor { ...@@ -235,7 +222,7 @@ public class TagProcessor {
/** /**
* Fills pagination. * Fills pagination.
* *
* @param dataModel the specified data model * @param dataModel the specified data model
* @param pageCount the specified page count * @param pageCount the specified page count
* @param currentPageNum the specified current page number * @param currentPageNum the specified current page number
...@@ -262,69 +249,12 @@ public class TagProcessor { ...@@ -262,69 +249,12 @@ public class TagProcessor {
dataModel.put(Pagination.PAGINATION_PAGE_NUMS, pageNums); dataModel.put(Pagination.PAGINATION_PAGE_NUMS, pageNums);
} }
/**
* Shows tags with the specified context.
*
* @param context the specified context
*/
@RequestProcessing(value = { "/tags.html"}, method = HTTPRequestMethod.GET)
public void showTags(final HTTPRequestContext context) {
final AbstractFreeMarkerRenderer renderer = new FrontRenderer();
context.setRenderer(renderer);
renderer.setTemplateName("tags.ftl");
final Map<String, Object> dataModel = renderer.getDataModel();
final HttpServletRequest request = context.getRequest();
final HttpServletResponse response = context.getResponse();
try {
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
Skins.fillLangs(preference.optString(Preference.LOCALE_STRING), (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), dataModel);
request.setAttribute(PageCaches.CACHED_OID, "No id");
final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale());
request.setAttribute(PageCaches.CACHED_TITLE, langs.get(PageTypes.TAGS.getLangeLabel()));
request.setAttribute(PageCaches.CACHED_TYPE, langs.get(PageTypes.TAGS.getLangeLabel()));
request.setAttribute(PageCaches.CACHED_LINK, "/tags.html");
final List<JSONObject> tags = tagQueryService.getTags();
tagQueryService.removeForUnpublishedArticles(tags);
Collections.sort(tags, Comparators.TAG_REF_CNT_COMPARATOR);
dataModel.put(Tag.TAGS, tags);
dataModel.put(Keys.PAGE_TYPE, PageTypes.TAGS);
filler.fillSide(request, dataModel, preference);
filler.fillBlogHeader(request, dataModel, preference);
filler.fillBlogFooter(request, dataModel, preference);
} catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
try {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
} catch (final IOException ex) {
LOGGER.error(ex.getMessage());
}
}
}
/** /**
* Gets the request page number from the specified request URI and tag title. * Gets the request page number from the specified request URI and tag title.
* *
* @param requestURI the specified request URI * @param requestURI the specified request URI
* @param tagTitle the specified tag title * @param tagTitle the specified tag title
* @return page number, returns {@code -1} if the specified request URI * @return page number, returns {@code -1} if the specified request URI can not convert to an number
* can not convert to an number
*/ */
private static int getCurrentPageNum(final String requestURI, final String tagTitle) { private static int getCurrentPageNum(final String requestURI, final String tagTitle) {
if (Strings.isEmptyOrNull(tagTitle)) { if (Strings.isEmptyOrNull(tagTitle)) {
...@@ -338,7 +268,7 @@ public class TagProcessor { ...@@ -338,7 +268,7 @@ public class TagProcessor {
/** /**
* Gets tag title from the specified URI. * Gets tag title from the specified URI.
* *
* @param requestURI the specified request URI * @param requestURI the specified request URI
* @return tag title * @return tag title
*/ */
......
...@@ -17,19 +17,15 @@ package org.b3log.solo.processor; ...@@ -17,19 +17,15 @@ package org.b3log.solo.processor;
import java.io.IOException; import java.io.IOException;
import java.sql.Connection;
import java.sql.Statement;
import javax.inject.Inject; import javax.inject.Inject;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.Latkes; import org.b3log.latke.Latkes;
import org.b3log.latke.RuntimeEnv;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.mail.MailService; import org.b3log.latke.mail.MailService;
import org.b3log.latke.mail.MailServiceFactory; import org.b3log.latke.mail.MailServiceFactory;
import org.b3log.latke.model.User; import org.b3log.latke.model.User;
import org.b3log.latke.repository.*; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.jdbc.util.Connections;
import org.b3log.latke.service.LangPropsService; import org.b3log.latke.service.LangPropsService;
import org.b3log.latke.service.ServiceException; import org.b3log.latke.service.ServiceException;
import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.servlet.HTTPRequestContext;
...@@ -37,7 +33,6 @@ import org.b3log.latke.servlet.HTTPRequestMethod; ...@@ -37,7 +33,6 @@ import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.annotation.RequestProcessing; import org.b3log.latke.servlet.annotation.RequestProcessing;
import org.b3log.latke.servlet.annotation.RequestProcessor; import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.TextHTMLRenderer; import org.b3log.latke.servlet.renderer.TextHTMLRenderer;
import org.b3log.latke.util.Strings;
import org.b3log.solo.SoloServletListener; import org.b3log.solo.SoloServletListener;
import org.b3log.solo.model.*; import org.b3log.solo.model.*;
import org.b3log.solo.repository.*; import org.b3log.solo.repository.*;
...@@ -52,7 +47,7 @@ import org.json.JSONObject; ...@@ -52,7 +47,7 @@ import org.json.JSONObject;
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="mailto:dongxu.wang@acm.org">Dongxu Wang</a> * @author <a href="mailto:dongxu.wang@acm.org">Dongxu Wang</a>
* @version 1.1.1.10, Aug 20, 2013 * @version 1.1.1.11, Oct 27, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
@RequestProcessor @RequestProcessor
...@@ -111,7 +106,7 @@ public class UpgradeProcessor { ...@@ -111,7 +106,7 @@ public class UpgradeProcessor {
/** /**
* Old version. * Old version.
*/ */
private static final String FROM_VER = "0.6.0"; private static final String FROM_VER = "0.6.1";
/** /**
* New version. * New version.
...@@ -177,26 +172,11 @@ public class UpgradeProcessor { ...@@ -177,26 +172,11 @@ public class UpgradeProcessor {
private void upgrade() throws Exception { private void upgrade() throws Exception {
LOGGER.log(Level.INFO, "Upgrading from version [{0}] to version [{1}]....", FROM_VER, TO_VER); LOGGER.log(Level.INFO, "Upgrading from version [{0}] to version [{1}]....", FROM_VER, TO_VER);
articleRepository.setCacheEnabled(false);
Transaction transaction = null; Transaction transaction = null;
try { try {
transaction = userRepository.beginTransaction(); transaction = userRepository.beginTransaction();
final RuntimeEnv runtimeEnv = Latkes.getRuntimeEnv();
if (RuntimeEnv.LOCAL == runtimeEnv || RuntimeEnv.BAE == runtimeEnv) {
final Connection connection = Connections.getConnection();
final Statement statement = connection.createStatement();
final String tablePrefix = Latkes.getLocalProperty("jdbc.tablePrefix");
final String tableName = Strings.isEmptyOrNull(tablePrefix) ? "preference" : tablePrefix + "_preference";
statement.execute("ALTER TABLE " + tableName + " DROP COLUMN blogHost");
connection.commit();
}
// Upgrades preference model // Upgrades preference model
final JSONObject preference = preferenceRepository.get(Preference.PREFERENCE); final JSONObject preference = preferenceRepository.get(Preference.PREFERENCE);
...@@ -213,8 +193,6 @@ public class UpgradeProcessor { ...@@ -213,8 +193,6 @@ public class UpgradeProcessor {
LOGGER.log(Level.ERROR, "Upgrade failed!", e); LOGGER.log(Level.ERROR, "Upgrade failed!", e);
throw new Exception("Upgrade failed from version [" + FROM_VER + "] to version [" + TO_VER + ']'); throw new Exception("Upgrade failed from version [" + FROM_VER + "] to version [" + TO_VER + ']');
} finally {
articleRepository.setCacheEnabled(true);
} }
LOGGER.log(Level.INFO, "Upgraded from version [{0}] to version [{1}] successfully :-)", FROM_VER, TO_VER); LOGGER.log(Level.INFO, "Upgraded from version [{0}] to version [{1}] successfully :-)", FROM_VER, TO_VER);
......
...@@ -24,7 +24,6 @@ import javax.servlet.http.HttpServletRequest; ...@@ -24,7 +24,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.service.LangPropsService; import org.b3log.latke.service.LangPropsService;
...@@ -33,11 +32,10 @@ import org.b3log.latke.servlet.HTTPRequestMethod; ...@@ -33,11 +32,10 @@ import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.annotation.RequestProcessing; import org.b3log.latke.servlet.annotation.RequestProcessing;
import org.b3log.latke.servlet.annotation.RequestProcessor; import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer; import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer;
import org.b3log.latke.servlet.renderer.freemarker.FreeMarkerRenderer;
import org.b3log.latke.util.Locales; import org.b3log.latke.util.Locales;
import org.b3log.latke.util.freemarker.Templates; import org.b3log.latke.util.freemarker.Templates;
import org.b3log.solo.model.PageTypes;
import org.b3log.solo.model.Preference; import org.b3log.solo.model.Preference;
import org.b3log.solo.processor.renderer.FrontRenderer;
import org.b3log.solo.processor.util.Filler; import org.b3log.solo.processor.util.Filler;
import org.b3log.solo.service.PreferenceQueryService; import org.b3log.solo.service.PreferenceQueryService;
import org.b3log.solo.util.Skins; import org.b3log.solo.util.Skins;
...@@ -102,7 +100,7 @@ public class UserTemplateProcessor { ...@@ -102,7 +100,7 @@ public class UserTemplateProcessor {
templateName = StringUtils.substringBefore(templateName, ".") + ".ftl"; templateName = StringUtils.substringBefore(templateName, ".") + ".ftl";
LOGGER.log(Level.DEBUG, "Shows page[requestURI={0}, templateName={1}]", new Object[] {requestURI, templateName}); LOGGER.log(Level.DEBUG, "Shows page[requestURI={0}, templateName={1}]", new Object[] {requestURI, templateName});
final AbstractFreeMarkerRenderer renderer = new FrontRenderer(); final AbstractFreeMarkerRenderer renderer = new FreeMarkerRenderer();
context.setRenderer(renderer); context.setRenderer(renderer);
renderer.setTemplateName(templateName); renderer.setTemplateName(templateName);
...@@ -127,16 +125,10 @@ public class UserTemplateProcessor { ...@@ -127,16 +125,10 @@ public class UserTemplateProcessor {
dataModel.putAll(langs); dataModel.putAll(langs);
final JSONObject preference = preferenceQueryService.getPreference(); final JSONObject preference = preferenceQueryService.getPreference();
dataModel.put(Keys.PAGE_TYPE, PageTypes.USER_TEMPLATE); filler.fillBlogHeader(request, response, dataModel, preference);
filler.fillBlogHeader(request, dataModel, preference); filler.fillUserTemplate(request, template, dataModel, preference);
filler.fillUserTemplate(template, dataModel, preference);
filler.fillBlogFooter(request, dataModel, preference); filler.fillBlogFooter(request, dataModel, preference);
Skins.fillLangs(preference.optString(Preference.LOCALE_STRING), (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), dataModel); Skins.fillLangs(preference.optString(Preference.LOCALE_STRING), (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), dataModel);
request.setAttribute(PageCaches.CACHED_OID, "No id");
request.setAttribute(PageCaches.CACHED_TITLE, requestURI);
request.setAttribute(PageCaches.CACHED_TYPE, langs.get(PageTypes.USER_TEMPLATE.getLangeLabel()));
request.setAttribute(PageCaches.CACHED_LINK, requestURI);
} catch (final Exception e) { } catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e); LOGGER.log(Level.ERROR, e.getMessage(), e);
......
...@@ -95,7 +95,8 @@ public class AdminConsole { ...@@ -95,7 +95,8 @@ public class AdminConsole {
/** /**
* Event manager. * Event manager.
*/ */
private EventManager eventManager = EventManager.getInstance(); @Inject
private EventManager eventManager;
/** /**
* Shows administrator index with the specified context. * Shows administrator index with the specified context.
......
...@@ -671,7 +671,7 @@ public class ArticleConsole { ...@@ -671,7 +671,7 @@ public class ArticleConsole {
renderer.setJSONObject(ret); renderer.setJSONObject(ret);
} catch (final ServiceException e) { } catch (final ServiceException e) {
LOGGER.log(Level.ERROR, e.getMessage(), e); LOGGER.log(Level.ERROR, e.getMessage());
final JSONObject jsonObject = QueryResults.defaultResult(); final JSONObject jsonObject = QueryResults.defaultResult();
......
/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.processor.renderer;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.b3log.latke.Keys;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.renderer.freemarker.CacheFreeMarkerRenderer;
import org.b3log.solo.model.Common;
import org.b3log.solo.processor.util.TopBars;
import org.b3log.solo.service.StatisticMgmtService;
/**
* <a href="http://freemarker.org">FreeMarker</a> HTTP response
* renderer.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.7, Jul 16, 2012
* @since 0.3.1
*/
public final class FrontRenderer extends CacheFreeMarkerRenderer {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(FrontRenderer.class.getName());
/**
* {@inheritDoc}
*
* <p>
* Puts the top bar replacement flag into data model.
* </p>
*/
@Override
protected void beforeRender(final HTTPRequestContext context) throws Exception {
LOGGER.log(Level.TRACE, "Before render....");
getDataModel().put(Common.TOP_BAR_REPLACEMENT_FLAG_KEY, Common.TOP_BAR_REPLACEMENT_FLAG);
}
@Override
protected void doRender(final String html, final HttpServletRequest request, final HttpServletResponse response)
throws Exception {
LOGGER.log(Level.TRACE, "Do render....");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter writer;
try {
writer = response.getWriter();
} catch (final Exception e) {
writer = new PrintWriter(response.getOutputStream());
}
if (response.isCommitted()) { // response has been sent redirect
writer.flush();
writer.close();
return;
}
final String pageContent = (String) request.getAttribute(PageCaches.CACHED_CONTENT);
String output = html;
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
if (null != pageContent) {
final TopBars topbars = beanManager.getReference(TopBars.class);
// Adds the top bar HTML content for output
final String topBarHTML = topbars.getTopBarHTML(request, response);
output = html.replace(Common.TOP_BAR_REPLACEMENT_FLAG, topBarHTML);
}
final StatisticMgmtService statisticMgmtService = beanManager.getReference(StatisticMgmtService.class);
// Inc blog view count
try {
statisticMgmtService.incBlogViewCount(request, response);
} catch (final Exception e) {
LOGGER.log(Level.WARN, "Incs blog view count failed", e);
}
// Write out
writer.write(output);
writer.flush();
writer.close();
}
/**
* {@inheritDoc}
*
* <p>
* Skips page caching if requested by mobile device.
* </p>
*/
@Override
protected void afterRender(final HTTPRequestContext context) throws Exception {
LOGGER.log(Level.TRACE, "After render....");
final HttpServletRequest request = context.getRequest();
if ("mobile".equals((String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME))) {
// Skips page caching if requested by mobile device
return;
}
super.afterRender(context);
}
}
...@@ -19,11 +19,13 @@ package org.b3log.solo.processor.util; ...@@ -19,11 +19,13 @@ package org.b3log.solo.processor.util;
import freemarker.template.Template; import freemarker.template.Template;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.time.DateFormatUtils; import org.apache.commons.lang.time.DateFormatUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
...@@ -56,6 +58,7 @@ import org.b3log.solo.service.StatisticQueryService; ...@@ -56,6 +58,7 @@ import org.b3log.solo.service.StatisticQueryService;
import org.b3log.solo.service.TagQueryService; import org.b3log.solo.service.TagQueryService;
import org.b3log.solo.service.UserQueryService; import org.b3log.solo.service.UserQueryService;
import org.b3log.solo.util.Thumbnails; import org.b3log.solo.util.Thumbnails;
import org.b3log.solo.util.comparator.Comparators;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
...@@ -65,7 +68,7 @@ import org.json.JSONObject; ...@@ -65,7 +68,7 @@ import org.json.JSONObject;
* Filler utilities. * Filler utilities.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.6.7, Jul 11, 2013 * @version 1.0.6.9, Oct 29, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
@Service @Service
...@@ -76,6 +79,12 @@ public class Filler { ...@@ -76,6 +79,12 @@ public class Filler {
*/ */
private static final Logger LOGGER = Logger.getLogger(Filler.class.getName()); private static final Logger LOGGER = Logger.getLogger(Filler.class.getName());
/**
* Topbar utilities.
*/
@Inject
private TopBars topBars;
/** /**
* Article repository. * Article repository.
*/ */
...@@ -153,6 +162,12 @@ public class Filler { ...@@ -153,6 +162,12 @@ public class Filler {
@Inject @Inject
private FillTagArticles fillTagArticles; private FillTagArticles fillTagArticles;
/**
* Event manager.
*/
@Inject
private EventManager eventManager;
/** /**
* Fills articles in index.ftl. * Fills articles in index.ftl.
* *
...@@ -272,6 +287,34 @@ public class Filler { ...@@ -272,6 +287,34 @@ public class Filler {
Stopwatchs.end(); Stopwatchs.end();
} }
/**
* Fills tags.
*
* @param dataModel data model
* @throws ServiceException service exception
*/
public void fillTags(final Map<String, Object> dataModel) throws ServiceException {
Stopwatchs.start("Fill Tags");
try {
final List<JSONObject> tags = tagQueryService.getTags();
tagQueryService.removeForUnpublishedArticles(tags);
Collections.sort(tags, Comparators.TAG_REF_CNT_COMPARATOR);
dataModel.put(Tag.TAGS, tags);
} catch (final JSONException e) {
LOGGER.log(Level.ERROR, "Fills tags failed", e);
throw new ServiceException(e);
} catch (final RepositoryException e) {
LOGGER.log(Level.ERROR, "Fills tagss failed", e);
throw new ServiceException(e);
} finally {
Stopwatchs.end();
}
Stopwatchs.end();
}
/** /**
* Fills most used tags. * Fills most used tags.
* *
...@@ -526,7 +569,7 @@ public class Filler { ...@@ -526,7 +569,7 @@ public class Filler {
data.setViewName("footer.ftl"); data.setViewName("footer.ftl");
data.setDataModel(dataModel); data.setDataModel(dataModel);
EventManager.getInstance().fireEventSynchronously(new Event<ViewLoadEventData>(Keys.FREEMARKER_ACTION, data)); eventManager.fireEventSynchronously(new Event<ViewLoadEventData>(Keys.FREEMARKER_ACTION, data));
if (Strings.isEmptyOrNull((String) dataModel.get(Plugin.PLUGINS))) { if (Strings.isEmptyOrNull((String) dataModel.get(Plugin.PLUGINS))) {
// There is no plugin for this template, fill ${plugins} with blank. // There is no plugin for this template, fill ${plugins} with blank.
dataModel.put(Plugin.PLUGINS, ""); dataModel.put(Plugin.PLUGINS, "");
...@@ -546,15 +589,21 @@ public class Filler { ...@@ -546,15 +589,21 @@ public class Filler {
* Fills header.ftl. * Fills header.ftl.
* *
* @param request the specified HTTP servlet request * @param request the specified HTTP servlet request
* @param response the specified HTTP servlet response
* @param dataModel data model * @param dataModel data model
* @param preference the specified preference * @param preference the specified preference
* @throws ServiceException service exception * @throws ServiceException service exception
*/ */
public void fillBlogHeader(final HttpServletRequest request, final Map<String, Object> dataModel, final JSONObject preference) public void fillBlogHeader(final HttpServletRequest request, final HttpServletResponse response,
final Map<String, Object> dataModel, final JSONObject preference)
throws ServiceException { throws ServiceException {
Stopwatchs.start("Fill Header"); Stopwatchs.start("Fill Header");
try { try {
LOGGER.debug("Filling header...."); LOGGER.debug("Filling header....");
final String topBarHTML = topBars.getTopBarHTML(request, response);
dataModel.put(Common.TOP_BAR, topBarHTML);
dataModel.put(Preference.ARTICLE_LIST_DISPLAY_COUNT, preference.getInt(Preference.ARTICLE_LIST_DISPLAY_COUNT)); dataModel.put(Preference.ARTICLE_LIST_DISPLAY_COUNT, preference.getInt(Preference.ARTICLE_LIST_DISPLAY_COUNT));
dataModel.put(Preference.ARTICLE_LIST_PAGINATION_WINDOW_SIZE, preference.getInt(Preference.ARTICLE_LIST_PAGINATION_WINDOW_SIZE)); dataModel.put(Preference.ARTICLE_LIST_PAGINATION_WINDOW_SIZE, preference.getInt(Preference.ARTICLE_LIST_PAGINATION_WINDOW_SIZE));
dataModel.put(Preference.LOCALE_STRING, preference.getString(Preference.LOCALE_STRING)); dataModel.put(Preference.LOCALE_STRING, preference.getString(Preference.LOCALE_STRING));
...@@ -564,6 +613,7 @@ public class Filler { ...@@ -564,6 +613,7 @@ public class Filler {
dataModel.put(Preference.META_KEYWORDS, preference.getString(Preference.META_KEYWORDS)); dataModel.put(Preference.META_KEYWORDS, preference.getString(Preference.META_KEYWORDS));
dataModel.put(Preference.META_DESCRIPTION, preference.getString(Preference.META_DESCRIPTION)); dataModel.put(Preference.META_DESCRIPTION, preference.getString(Preference.META_DESCRIPTION));
dataModel.put(Common.YEAR, String.valueOf(Calendar.getInstance().get(Calendar.YEAR))); dataModel.put(Common.YEAR, String.valueOf(Calendar.getInstance().get(Calendar.YEAR)));
dataModel.put(Common.IS_LOGGED_IN, null != userQueryService.getCurrentUser(request));
final String noticeBoard = preference.getString(Preference.NOTICE_BOARD); final String noticeBoard = preference.getString(Preference.NOTICE_BOARD);
...@@ -686,13 +736,14 @@ public class Filler { ...@@ -686,13 +736,14 @@ public class Filler {
/** /**
* Fills the specified template. * Fills the specified template.
* *
* @param request the specified HTTP servlet request
* @param template the specified template * @param template the specified template
* @param dataModel data model * @param dataModel data model
* @param preference the specified preference * @param preference the specified preference
* @throws ServiceException service exception * @throws ServiceException service exception
*/ */
public void fillUserTemplate(final Template template, final Map<String, Object> dataModel, final JSONObject preference) public void fillUserTemplate(final HttpServletRequest request, final Template template,
throws ServiceException { final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
Stopwatchs.start("Fill User Template[name=" + template.getName() + "]"); Stopwatchs.start("Fill User Template[name=" + template.getName() + "]");
try { try {
LOGGER.log(Level.DEBUG, "Filling user template[name{0}]", template.getName()); LOGGER.log(Level.DEBUG, "Filling user template[name{0}]", template.getName());
...@@ -701,6 +752,10 @@ public class Filler { ...@@ -701,6 +752,10 @@ public class Filler {
fillLinks(dataModel); fillLinks(dataModel);
} }
if (Templates.hasExpression(template, "<#list tags as tag>")) {
fillTags(dataModel);
}
if (Templates.hasExpression(template, "<#list recentComments as comment>")) { if (Templates.hasExpression(template, "<#list recentComments as comment>")) {
fillRecentComments(dataModel, preference); fillRecentComments(dataModel, preference);
} }
...@@ -721,6 +776,10 @@ public class Filler { ...@@ -721,6 +776,10 @@ public class Filler {
fillArchiveDates(dataModel, preference); fillArchiveDates(dataModel, preference);
} }
if (Templates.hasExpression(template, "<#include \"side.ftl\"/>")) {
fillSide(request, dataModel, preference);
}
final String noticeBoard = preference.getString(Preference.NOTICE_BOARD); final String noticeBoard = preference.getString(Preference.NOTICE_BOARD);
dataModel.put(Preference.NOTICE_BOARD, noticeBoard); dataModel.put(Preference.NOTICE_BOARD, noticeBoard);
...@@ -783,10 +842,11 @@ public class Filler { ...@@ -783,10 +842,11 @@ public class Filler {
} }
/** /**
* Sets some extra properties into the specified article with the specified * Sets some extra properties into the specified article with the specified author and preference, performs content and abstract editor
* author and preference, performs content and abstract editor processing. * processing.
* *
* <p> Article ext properties: * <p>
* Article ext properties:
* <pre> * <pre>
* { * {
* ...., * ....,
...@@ -828,10 +888,10 @@ public class Filler { ...@@ -828,10 +888,10 @@ public class Filler {
} }
/** /**
* Sets some extra properties into the specified article with the specified * Sets some extra properties into the specified article with the specified preference, performs content and abstract editor processing.
* preference, performs content and abstract editor processing.
* *
* <p> Article ext properties: * <p>
* Article ext properties:
* <pre> * <pre>
* { * {
* ...., * ....,
...@@ -872,14 +932,14 @@ public class Filler { ...@@ -872,14 +932,14 @@ public class Filler {
} }
/** /**
* Sets some extra properties into the specified article with the specified * Sets some extra properties into the specified article with the specified author and preference.
* author and preference.
* *
* <p> The batch version of method * <p>
* {@linkplain #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)}. * The batch version of method {@linkplain #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)}.
* </p> * </p>
* *
* <p> Article ext properties: * <p>
* Article ext properties:
* <pre> * <pre>
* { * {
* ...., * ....,
...@@ -903,14 +963,14 @@ public class Filler { ...@@ -903,14 +963,14 @@ public class Filler {
} }
/** /**
* Sets some extra properties into the specified article with the specified * Sets some extra properties into the specified article with the specified preference.
* preference.
* *
* <p> The batch version of method * <p>
* {@linkplain #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)}. * The batch version of method {@linkplain #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)}.
* </p> * </p>
* *
* <p> Article ext properties: * <p>
* Article ext properties:
* <pre> * <pre>
* { * {
* ...., * ....,
...@@ -935,12 +995,12 @@ public class Filler { ...@@ -935,12 +995,12 @@ public class Filler {
/** /**
* Processes the abstract of the specified article with the specified preference. * Processes the abstract of the specified article with the specified preference.
* *
* <p> * <p>
* <ul> * <ul>
* <li>If the abstract is {@code null}, sets it with ""</li> * <li>If the abstract is {@code null}, sets it with ""</li>
* <li>If user configured preference "titleOnly", sets the abstract with ""</li> * <li>If user configured preference "titleOnly", sets the abstract with ""</li>
* <li>If user configured preference "titleAndContent", sets the abstract with the content of the article</li> * <li>If user configured preference "titleAndContent", sets the abstract with the content of the article</li>
* </ul> * </ul>
* </p> * </p>
* *
* @param preference the specified preference * @param preference the specified preference
......
...@@ -136,8 +136,6 @@ public class TopBars { ...@@ -136,8 +136,6 @@ public class TopBars {
topBarModel.put(Common.IS_ADMIN, Role.ADMIN_ROLE.equals(currentUser.getString(User.USER_ROLE))); topBarModel.put(Common.IS_ADMIN, Role.ADMIN_ROLE.equals(currentUser.getString(User.USER_ROLE)));
topBarModel.put(Common.IS_VISITOR, Role.VISITOR_ROLE.equals(currentUser.getString(User.USER_ROLE))); topBarModel.put(Common.IS_VISITOR, Role.VISITOR_ROLE.equals(currentUser.getString(User.USER_ROLE)));
topBarModel.put("clearAllCacheLabel", langPropsService.get("clearAllCacheLabel"));
topBarModel.put("clearCacheLabel", langPropsService.get("clearCacheLabel"));
topBarModel.put("adminLabel", langPropsService.get("adminLabel")); topBarModel.put("adminLabel", langPropsService.get("adminLabel"));
topBarModel.put("logoutLabel", langPropsService.get("logoutLabel")); topBarModel.put("logoutLabel", langPropsService.get("logoutLabel"));
......
...@@ -39,7 +39,7 @@ import org.json.JSONObject; ...@@ -39,7 +39,7 @@ import org.json.JSONObject;
* @since 0.3.1 * @since 0.3.1
*/ */
@Repository @Repository
public final class ArchiveDateArticleRepositoryImpl extends AbstractRepository implements ArchiveDateArticleRepository { public class ArchiveDateArticleRepositoryImpl extends AbstractRepository implements ArchiveDateArticleRepository {
/** /**
* Public constructor. * Public constructor.
......
...@@ -45,7 +45,7 @@ import org.json.JSONObject; ...@@ -45,7 +45,7 @@ import org.json.JSONObject;
* @since 0.3.1 * @since 0.3.1
*/ */
@Repository @Repository
public final class ArchiveDateRepositoryImpl extends AbstractRepository implements ArchiveDateRepository { public class ArchiveDateRepositoryImpl extends AbstractRepository implements ArchiveDateRepository {
/** /**
* Logger. * Logger.
......
...@@ -46,7 +46,7 @@ import org.json.JSONObject; ...@@ -46,7 +46,7 @@ import org.json.JSONObject;
* @since 0.3.1 * @since 0.3.1
*/ */
@Repository @Repository
public final class ArticleRepositoryImpl extends AbstractRepository implements ArticleRepository { public class ArticleRepositoryImpl extends AbstractRepository implements ArticleRepository {
/** /**
* Logger. * Logger.
......
...@@ -16,12 +16,10 @@ ...@@ -16,12 +16,10 @@
package org.b3log.solo.repository.impl; package org.b3log.solo.repository.impl;
import java.io.Serializable;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.cache.Cache;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.repository.AbstractRepository; import org.b3log.latke.repository.AbstractRepository;
...@@ -48,7 +46,7 @@ import org.json.JSONObject; ...@@ -48,7 +46,7 @@ import org.json.JSONObject;
* @since 0.3.1 * @since 0.3.1
*/ */
@Repository @Repository
public final class CommentRepositoryImpl extends AbstractRepository implements CommentRepository { public class CommentRepositoryImpl extends AbstractRepository implements CommentRepository {
/** /**
* Logger. * Logger.
...@@ -68,11 +66,6 @@ public final class CommentRepositoryImpl extends AbstractRepository implements C ...@@ -68,11 +66,6 @@ public final class CommentRepositoryImpl extends AbstractRepository implements C
super(Comment.COMMENT); super(Comment.COMMENT);
} }
/**
* Recent comments query results cache key.
*/
public static final String RECENT_CMTS_CACHE_KEY = "recentCMTs";
@Override @Override
public int removeComments(final String onId) throws RepositoryException { public int removeComments(final String onId) throws RepositoryException {
final List<JSONObject> comments = getComments(onId, 1, Integer.MAX_VALUE); final List<JSONObject> comments = getComments(onId, 1, Integer.MAX_VALUE);
...@@ -104,15 +97,6 @@ public final class CommentRepositoryImpl extends AbstractRepository implements C ...@@ -104,15 +97,6 @@ public final class CommentRepositoryImpl extends AbstractRepository implements C
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<JSONObject> getRecentComments(final int num) throws RepositoryException { public List<JSONObject> getRecentComments(final int num) throws RepositoryException {
if (isCacheEnabled()) {
final Cache<String, Serializable> cache = getCache();
final Object ret = cache.get(RECENT_CMTS_CACHE_KEY);
if (null != ret) {
return (List<JSONObject>) ret;
}
}
final Query query = new Query().addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).setCurrentPageNum(1).setPageSize(num).setPageCount( final Query query = new Query().addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).setCurrentPageNum(1).setPageSize(num).setPageCount(
1); 1);
...@@ -126,12 +110,6 @@ public final class CommentRepositoryImpl extends AbstractRepository implements C ...@@ -126,12 +110,6 @@ public final class CommentRepositoryImpl extends AbstractRepository implements C
// Removes unpublished article related comments // Removes unpublished article related comments
removeForUnpublishedArticles(ret); removeForUnpublishedArticles(ret);
if (isCacheEnabled()) {
final Cache<String, Serializable> cache = getCache();
cache.put(RECENT_CMTS_CACHE_KEY, (Serializable) ret);
}
return ret; return ret;
} }
......
...@@ -38,7 +38,7 @@ import org.json.JSONObject; ...@@ -38,7 +38,7 @@ import org.json.JSONObject;
* @since 0.3.1 * @since 0.3.1
*/ */
@Repository @Repository
public final class LinkRepositoryImpl extends AbstractRepository implements LinkRepository { public class LinkRepositoryImpl extends AbstractRepository implements LinkRepository {
/** /**
* Public constructor. * Public constructor.
......
...@@ -30,7 +30,7 @@ import org.b3log.solo.repository.OptionRepository; ...@@ -30,7 +30,7 @@ import org.b3log.solo.repository.OptionRepository;
* @since 0.6.0 * @since 0.6.0
*/ */
@Repository @Repository
public final class OptionRepositoryImpl extends AbstractRepository implements OptionRepository { public class OptionRepositoryImpl extends AbstractRepository implements OptionRepository {
/** /**
* Public constructor. * Public constructor.
......
...@@ -40,7 +40,7 @@ import org.json.JSONObject; ...@@ -40,7 +40,7 @@ import org.json.JSONObject;
* @since 0.3.1 * @since 0.3.1
*/ */
@Repository @Repository
public final class PageRepositoryImpl extends AbstractRepository implements PageRepository { public class PageRepositoryImpl extends AbstractRepository implements PageRepository {
/** /**
* Public constructor. * Public constructor.
......
...@@ -30,7 +30,7 @@ import org.b3log.solo.repository.PluginRepository; ...@@ -30,7 +30,7 @@ import org.b3log.solo.repository.PluginRepository;
* @since 0.3.1 * @since 0.3.1
*/ */
@Repository @Repository
public final class PluginRepositoryImpl extends AbstractRepository implements PluginRepository { public class PluginRepositoryImpl extends AbstractRepository implements PluginRepository {
/** /**
* Public constructor. * Public constructor.
......
...@@ -32,7 +32,7 @@ import org.json.JSONObject; ...@@ -32,7 +32,7 @@ import org.json.JSONObject;
* @since 0.3.1 * @since 0.3.1
*/ */
@Repository @Repository
public final class PreferenceRepositoryImpl extends AbstractRepository implements PreferenceRepository { public class PreferenceRepositoryImpl extends AbstractRepository implements PreferenceRepository {
/** /**
* Public constructor. * Public constructor.
......
...@@ -16,14 +16,10 @@ ...@@ -16,14 +16,10 @@
package org.b3log.solo.repository.impl; package org.b3log.solo.repository.impl;
import org.b3log.latke.Latkes;
import org.b3log.latke.repository.AbstractRepository; import org.b3log.latke.repository.AbstractRepository;
import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.repository.annotation.Repository; import org.b3log.latke.repository.annotation.Repository;
import org.b3log.solo.model.Statistic; import org.b3log.solo.model.Statistic;
import org.b3log.solo.repository.StatisticRepository; import org.b3log.solo.repository.StatisticRepository;
import org.b3log.solo.service.StatisticMgmtService;
import org.json.JSONObject;
/** /**
...@@ -34,7 +30,7 @@ import org.json.JSONObject; ...@@ -34,7 +30,7 @@ import org.json.JSONObject;
* @since 0.3.1 * @since 0.3.1
*/ */
@Repository @Repository
public final class StatisticRepositoryImpl extends AbstractRepository implements StatisticRepository { public class StatisticRepositoryImpl extends AbstractRepository implements StatisticRepository {
/** /**
* Public constructor. * Public constructor.
...@@ -42,13 +38,4 @@ public final class StatisticRepositoryImpl extends AbstractRepository implements ...@@ -42,13 +38,4 @@ public final class StatisticRepositoryImpl extends AbstractRepository implements
public StatisticRepositoryImpl() { public StatisticRepositoryImpl() {
super(Statistic.STATISTIC); super(Statistic.STATISTIC);
} }
@Override
public void update(final String id, final JSONObject jsonObject) throws RepositoryException {
super.update(id, jsonObject);
if (Latkes.isDataCacheEnabled()) {
getCache().put(StatisticMgmtService.REPOSITORY_CACHE_KEY_PREFIX + Statistic.STATISTIC, jsonObject);
}
}
} }
...@@ -41,7 +41,7 @@ import org.json.JSONObject; ...@@ -41,7 +41,7 @@ import org.json.JSONObject;
* @since 0.3.1 * @since 0.3.1
*/ */
@Repository @Repository
public final class TagArticleRepositoryImpl extends AbstractRepository implements TagArticleRepository { public class TagArticleRepositoryImpl extends AbstractRepository implements TagArticleRepository {
/** /**
* Public constructor. * Public constructor.
......
...@@ -43,7 +43,7 @@ import org.json.JSONObject; ...@@ -43,7 +43,7 @@ import org.json.JSONObject;
* @since 0.3.1 * @since 0.3.1
*/ */
@Repository @Repository
public final class TagRepositoryImpl extends AbstractRepository implements TagRepository { public class TagRepositoryImpl extends AbstractRepository implements TagRepository {
/** /**
* Public constructor. * Public constructor.
......
...@@ -38,7 +38,7 @@ import org.json.JSONObject; ...@@ -38,7 +38,7 @@ import org.json.JSONObject;
* @since 0.3.1 * @since 0.3.1
*/ */
@Repository @Repository
public final class UserRepositoryImpl extends AbstractRepository implements UserRepository { public class UserRepositoryImpl extends AbstractRepository implements UserRepository {
/** /**
* Public constructor. * Public constructor.
......
...@@ -49,7 +49,6 @@ import org.b3log.solo.repository.TagArticleRepository; ...@@ -49,7 +49,6 @@ import org.b3log.solo.repository.TagArticleRepository;
import org.b3log.solo.repository.TagRepository; import org.b3log.solo.repository.TagRepository;
import org.b3log.solo.repository.UserRepository; import org.b3log.solo.repository.UserRepository;
import org.b3log.solo.util.Comments; import org.b3log.solo.util.Comments;
import org.b3log.solo.util.TimeZones;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
...@@ -59,7 +58,7 @@ import org.json.JSONObject; ...@@ -59,7 +58,7 @@ import org.json.JSONObject;
* Article management service. * Article management service.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.1.5, Jan 30, 2013 * @version 1.0.1.6, Oct 26, 2013
* @since 0.3.5 * @since 0.3.5
*/ */
@Service @Service
...@@ -133,7 +132,8 @@ public class ArticleMgmtService { ...@@ -133,7 +132,8 @@ public class ArticleMgmtService {
/** /**
* Event manager. * Event manager.
*/ */
private EventManager eventManager = EventManager.getInstance(); @Inject
private EventManager eventManager;
/** /**
* Language service. * Language service.
...@@ -293,8 +293,7 @@ public class ArticleMgmtService { ...@@ -293,8 +293,7 @@ public class ArticleMgmtService {
// Set date // Set date
article.put(ARTICLE_UPDATE_DATE, oldArticle.get(ARTICLE_UPDATE_DATE)); article.put(ARTICLE_UPDATE_DATE, oldArticle.get(ARTICLE_UPDATE_DATE));
final JSONObject preference = preferenceQueryService.getPreference(); final JSONObject preference = preferenceQueryService.getPreference();
final String timeZoneId = preference.getString(Preference.TIME_ZONE_ID); final Date date = new Date();
final Date date = TimeZones.getTime(timeZoneId);
// The article to update has no sign // The article to update has no sign
if (!article.has(Article.ARTICLE_SIGN_ID)) { if (!article.has(Article.ARTICLE_SIGN_ID)) {
...@@ -437,18 +436,12 @@ public class ArticleMgmtService { ...@@ -437,18 +436,12 @@ public class ArticleMgmtService {
transaction.commit(); transaction.commit();
return ret; return ret;
} catch (final ServiceException e) {
if (transaction.isActive()) {
transaction.rollback();
}
throw e;
} catch (final Exception e) { } catch (final Exception e) {
if (transaction.isActive()) { if (transaction.isActive()) {
transaction.rollback(); transaction.rollback();
} }
throw new ServiceException(e); throw new ServiceException(e.getMessage());
} }
} }
...@@ -478,8 +471,7 @@ public class ArticleMgmtService { ...@@ -478,8 +471,7 @@ public class ArticleMgmtService {
article.put(Article.ARTICLE_VIEW_COUNT, 0); article.put(Article.ARTICLE_VIEW_COUNT, 0);
// Step 3: Set create/updat date // Step 3: Set create/updat date
final JSONObject preference = preferenceQueryService.getPreference(); final JSONObject preference = preferenceQueryService.getPreference();
final String timeZoneId = preference.optString(Preference.TIME_ZONE_ID); final Date date = new Date();
final Date date = TimeZones.getTime(timeZoneId);
if (!article.has(Article.ARTICLE_CREATE_DATE)) { if (!article.has(Article.ARTICLE_CREATE_DATE)) {
article.put(Article.ARTICLE_CREATE_DATE, date); article.put(Article.ARTICLE_CREATE_DATE, date);
...@@ -610,7 +602,6 @@ public class ArticleMgmtService { ...@@ -610,7 +602,6 @@ public class ArticleMgmtService {
throws ServiceException { throws ServiceException {
final Transaction transaction = articleRepository.beginTransaction(); final Transaction transaction = articleRepository.beginTransaction();
transaction.clearQueryCache(false);
try { try {
final List<JSONObject> randomArticles = articleRepository.getRandomly(updateCnt); final List<JSONObject> randomArticles = articleRepository.getRandomly(updateCnt);
...@@ -1151,7 +1142,6 @@ public class ArticleMgmtService { ...@@ -1151,7 +1142,6 @@ public class ArticleMgmtService {
throw new ServiceException(langPropsService.get("duplicatedPermalinkLabel")); throw new ServiceException(langPropsService.get("duplicatedPermalinkLabel"));
} }
// TODO: SBC case
return ret.replaceAll(" ", "-"); return ret.replaceAll(" ", "-");
} }
...@@ -1190,7 +1180,6 @@ public class ArticleMgmtService { ...@@ -1190,7 +1180,6 @@ public class ArticleMgmtService {
} }
} }
// TODO: SBC case
return ret.replaceAll(" ", "-"); return ret.replaceAll(" ", "-");
} }
......
...@@ -47,7 +47,6 @@ import org.b3log.solo.repository.CommentRepository; ...@@ -47,7 +47,6 @@ import org.b3log.solo.repository.CommentRepository;
import org.b3log.solo.repository.PageRepository; import org.b3log.solo.repository.PageRepository;
import org.b3log.solo.util.Comments; import org.b3log.solo.util.Comments;
import org.b3log.solo.util.Thumbnails; import org.b3log.solo.util.Thumbnails;
import org.b3log.solo.util.TimeZones;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
...@@ -106,7 +105,8 @@ public class CommentMgmtService { ...@@ -106,7 +105,8 @@ public class CommentMgmtService {
/** /**
* Event manager. * Event manager.
*/ */
private static EventManager eventManager = EventManager.getInstance(); @Inject
private static EventManager eventManager;
/** /**
* Default user thumbnail. * Default user thumbnail.
...@@ -401,8 +401,7 @@ public class CommentMgmtService { ...@@ -401,8 +401,7 @@ public class CommentMgmtService {
comment.put(Comment.COMMENT_URL, commentURL); comment.put(Comment.COMMENT_URL, commentURL);
comment.put(Comment.COMMENT_CONTENT, commentContent); comment.put(Comment.COMMENT_CONTENT, commentContent);
final JSONObject preference = preferenceQueryService.getPreference(); final JSONObject preference = preferenceQueryService.getPreference();
final String timeZoneId = preference.getString(Preference.TIME_ZONE_ID); final Date date = new Date();
final Date date = TimeZones.getTime(timeZoneId);
comment.put(Comment.COMMENT_DATE, date); comment.put(Comment.COMMENT_DATE, date);
ret.put(Comment.COMMENT_DATE, DateFormatUtils.format(date, "yyyy-MM-dd hh:mm:ss")); ret.put(Comment.COMMENT_DATE, DateFormatUtils.format(date, "yyyy-MM-dd hh:mm:ss"));
...@@ -521,8 +520,7 @@ public class CommentMgmtService { ...@@ -521,8 +520,7 @@ public class CommentMgmtService {
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, requestJSONObject.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID)); comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, requestJSONObject.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID));
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, requestJSONObject.optString(Comment.COMMENT_ORIGINAL_COMMENT_NAME)); comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, requestJSONObject.optString(Comment.COMMENT_ORIGINAL_COMMENT_NAME));
final JSONObject preference = preferenceQueryService.getPreference(); final JSONObject preference = preferenceQueryService.getPreference();
final String timeZoneId = preference.getString(Preference.TIME_ZONE_ID); final Date date = new Date();
final Date date = TimeZones.getTime(timeZoneId);
comment.put(Comment.COMMENT_DATE, date); comment.put(Comment.COMMENT_DATE, date);
ret.put(Comment.COMMENT_DATE, DateFormatUtils.format(date, "yyyy-MM-dd hh:mm:ss")); ret.put(Comment.COMMENT_DATE, DateFormatUtils.format(date, "yyyy-MM-dd hh:mm:ss"));
......
...@@ -33,6 +33,7 @@ import org.b3log.latke.logging.Level; ...@@ -33,6 +33,7 @@ import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.model.Role; import org.b3log.latke.model.Role;
import org.b3log.latke.model.User; import org.b3log.latke.model.User;
import org.b3log.latke.plugin.PluginManager;
import org.b3log.latke.repository.RepositoryException; import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.repository.Transaction; import org.b3log.latke.repository.Transaction;
import org.b3log.latke.repository.jdbc.util.JdbcRepositories; import org.b3log.latke.repository.jdbc.util.JdbcRepositories;
...@@ -142,6 +143,12 @@ public class InitService { ...@@ -142,6 +143,12 @@ public class InitService {
@Inject @Inject
private LangPropsService langPropsService; private LangPropsService langPropsService;
/**
* Plugin manager.
*/
@Inject
private PluginManager pluginManager;
/** /**
* Determines Solo had been initialized. * Determines Solo had been initialized.
* *
...@@ -252,6 +259,8 @@ public class InitService { ...@@ -252,6 +259,8 @@ public class InitService {
LOGGER.log(Level.ERROR, "Hello World error?!", e); LOGGER.log(Level.ERROR, "Hello World error?!", e);
} }
pluginManager.load();
} }
/** /**
...@@ -274,7 +283,7 @@ public class InitService { ...@@ -274,7 +283,7 @@ public class InitService {
article.put(Article.ARTICLE_SIGN_ID, "1"); article.put(Article.ARTICLE_SIGN_ID, "1");
article.put(Article.ARTICLE_COMMENT_COUNT, 1); article.put(Article.ARTICLE_COMMENT_COUNT, 1);
article.put(Article.ARTICLE_VIEW_COUNT, 0); article.put(Article.ARTICLE_VIEW_COUNT, 0);
final Date date = TimeZones.getTime(INIT_TIME_ZONE_ID); final Date date = new Date();
article.put(Article.ARTICLE_CREATE_DATE, date); article.put(Article.ARTICLE_CREATE_DATE, date);
article.put(Article.ARTICLE_UPDATE_DATE, date); article.put(Article.ARTICLE_UPDATE_DATE, date);
...@@ -552,7 +561,6 @@ public class InitService { ...@@ -552,7 +561,6 @@ public class InitService {
ret.put(ENABLE_ARTICLE_UPDATE_HINT, Default.DEFAULT_ENABLE_ARTICLE_UPDATE_HINT); ret.put(ENABLE_ARTICLE_UPDATE_HINT, Default.DEFAULT_ENABLE_ARTICLE_UPDATE_HINT);
ret.put(SIGNS, Default.DEFAULT_SIGNS); ret.put(SIGNS, Default.DEFAULT_SIGNS);
ret.put(TIME_ZONE_ID, Default.DEFAULT_TIME_ZONE); ret.put(TIME_ZONE_ID, Default.DEFAULT_TIME_ZONE);
ret.put(PAGE_CACHE_ENABLED, Default.DEFAULT_PAGE_CACHE_ENABLED);
ret.put(ALLOW_VISIT_DRAFT_VIA_PERMALINK, Default.DEFAULT_ALLOW_VISIT_DRAFT_VIA_PERMALINK); ret.put(ALLOW_VISIT_DRAFT_VIA_PERMALINK, Default.DEFAULT_ALLOW_VISIT_DRAFT_VIA_PERMALINK);
ret.put(COMMENTABLE, Default.DEFAULT_COMMENTABLE); ret.put(COMMENTABLE, Default.DEFAULT_COMMENTABLE);
ret.put(VERSION, SoloServletListener.VERSION); ret.put(VERSION, SoloServletListener.VERSION);
...@@ -598,12 +606,6 @@ public class InitService { ...@@ -598,12 +606,6 @@ public class InitService {
TimeZones.setTimeZone(INIT_TIME_ZONE_ID); TimeZones.setTimeZone(INIT_TIME_ZONE_ID);
if (Default.DEFAULT_PAGE_CACHE_ENABLED) {
Latkes.enablePageCache();
} else {
Latkes.disablePageCache();
}
ret.put(Keys.OBJECT_ID, PREFERENCE); ret.put(Keys.OBJECT_ID, PREFERENCE);
preferenceRepository.add(ret); preferenceRepository.add(ret);
...@@ -701,4 +703,13 @@ public class InitService { ...@@ -701,4 +703,13 @@ public class InitService {
public void setLangPropsService(final LangPropsService langPropsService) { public void setLangPropsService(final LangPropsService langPropsService) {
this.langPropsService = langPropsService; this.langPropsService = langPropsService;
} }
/**
* Sets the plugin manager with the specified plugin manager.
*
* @param pluginManager the specified plugin manager
*/
public void setPluginManager(final PluginManager pluginManager) {
this.pluginManager = pluginManager;
}
} }
...@@ -160,7 +160,6 @@ public class PageMgmtService { ...@@ -160,7 +160,6 @@ public class PageMgmtService {
} }
} }
// TODO: SBC case
newPage.put(Page.PAGE_PERMALINK, permalink.replaceAll(" ", "-")); newPage.put(Page.PAGE_PERMALINK, permalink.replaceAll(" ", "-"));
if (!oldPage.getString(Page.PAGE_PERMALINK).equals(permalink)) { // The permalink has been updated if (!oldPage.getString(Page.PAGE_PERMALINK).equals(permalink)) { // The permalink has been updated
...@@ -274,9 +273,8 @@ public class PageMgmtService { ...@@ -274,9 +273,8 @@ public class PageMgmtService {
} }
} }
// TODO: SBC case
page.put(Page.PAGE_PERMALINK, permalink.replaceAll(" ", "-")); page.put(Page.PAGE_PERMALINK, permalink.replaceAll(" ", "-"));
// Editor type // Editor type
final JSONObject preference = preferenceQueryService.getPreference(); final JSONObject preference = preferenceQueryService.getPreference();
......
...@@ -19,6 +19,7 @@ package org.b3log.solo.service; ...@@ -19,6 +19,7 @@ package org.b3log.solo.service;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.inject.Inject; import javax.inject.Inject;
import org.b3log.latke.Latkes;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.repository.RepositoryException; import org.b3log.latke.repository.RepositoryException;
...@@ -32,7 +33,7 @@ import org.b3log.solo.repository.PageRepository; ...@@ -32,7 +33,7 @@ import org.b3log.solo.repository.PageRepository;
* Permalink query service. * Permalink query service.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.0, Jun 21, 2013 * @version 1.0.0.1, Oct 26, 2013
* @since 0.6.1 * @since 0.6.1
*/ */
@Service @Service
...@@ -65,7 +66,7 @@ public class PermalinkQueryService { ...@@ -65,7 +66,7 @@ public class PermalinkQueryService {
"/login", "/logout", "/forgot", "/get-article-content", "/admin-index.do", "/admin-article.do", "/admin-article-list.do", "/login", "/logout", "/forgot", "/get-article-content", "/admin-index.do", "/admin-article.do", "/admin-article-list.do",
"/admin-link-list.do", "/admin-preference.do", "/admin-file-list.do", "/admin-page-list.do", "/admin-others.do", "/admin-link-list.do", "/admin-preference.do", "/admin-file-list.do", "/admin-page-list.do", "/admin-others.do",
"/admin-draft-list.do", "/admin-user-list.do", "/admin-plugin-list.do", "/admin-main.do", "/admin-about.do", "/admin-label", "/admin-draft-list.do", "/admin-user-list.do", "/admin-plugin-list.do", "/admin-main.do", "/admin-about.do", "/admin-label",
"/admin-about.do", "/rm-all-data.do", "/init", "/clear-cache.do", "/register.html" "/admin-about.do", "/rm-all-data.do", "/init", "/register.html"
}; };
/** /**
...@@ -148,8 +149,7 @@ public class PermalinkQueryService { ...@@ -148,8 +149,7 @@ public class PermalinkQueryService {
* @param permalink the specified user-defined permalink * @param permalink the specified user-defined permalink
* @return {@code true} if invalid, returns {@code false} otherwise * @return {@code true} if invalid, returns {@code false} otherwise
*/ */
private static boolean invalidUserDefinedPermalinkFormat( private static boolean invalidUserDefinedPermalinkFormat(final String permalink) {
final String permalink) {
if (Strings.isEmptyOrNull(permalink)) { if (Strings.isEmptyOrNull(permalink)) {
return true; return true;
} }
...@@ -159,8 +159,7 @@ public class PermalinkQueryService { ...@@ -159,8 +159,7 @@ public class PermalinkQueryService {
} }
if (Strings.isNumeric(permalink.substring(1))) { if (Strings.isNumeric(permalink.substring(1))) {
// See issue 120 (http://code.google.com/p/b3log-solo/issues/detail?id=120#c4) // See issue 120 (http://code.google.com/p/b3log-solo/issues/detail?id=120#c4) for more details
// for more details
return true; return true;
} }
...@@ -176,9 +175,7 @@ public class PermalinkQueryService { ...@@ -176,9 +175,7 @@ public class PermalinkQueryService {
} }
} }
// FIXME: URL format check return !Strings.isURL(Latkes.getServer() + permalink);
return false;
} }
/** /**
......
...@@ -65,6 +65,18 @@ public class PluginMgmtService { ...@@ -65,6 +65,18 @@ public class PluginMgmtService {
*/ */
@Inject @Inject
private LangPropsService langPropsService; private LangPropsService langPropsService;
/**
* Initialization service.
*/
@Inject
private InitService initService;
/**
* Plugin manager.
*/
@Inject
private PluginManager pluginManager;
/** /**
* Updates datastore plugin descriptions with the specified plugins. * Updates datastore plugin descriptions with the specified plugins.
...@@ -73,13 +85,14 @@ public class PluginMgmtService { ...@@ -73,13 +85,14 @@ public class PluginMgmtService {
* @throws Exception exception * @throws Exception exception
*/ */
public void refresh(final List<AbstractPlugin> plugins) throws Exception { public void refresh(final List<AbstractPlugin> plugins) throws Exception {
if (!initService.isInited()) {
return;
}
final JSONObject result = pluginRepository.get(new Query()); final JSONObject result = pluginRepository.get(new Query());
final JSONArray pluginArray = result.getJSONArray(Keys.RESULTS); final JSONArray pluginArray = result.getJSONArray(Keys.RESULTS);
final List<JSONObject> persistedPlugins = CollectionUtils.jsonArrayToList(pluginArray); final List<JSONObject> persistedPlugins = CollectionUtils.jsonArrayToList(pluginArray);
// Disables plugin repository cache to avoid remove all cache
pluginRepository.setCacheEnabled(false);
try { try {
// Reads plugin status from datastore and clear plugin datastore // Reads plugin status from datastore and clear plugin datastore
for (final JSONObject oldPluginDesc : persistedPlugins) { for (final JSONObject oldPluginDesc : persistedPlugins) {
...@@ -115,8 +128,6 @@ public class PluginMgmtService { ...@@ -115,8 +128,6 @@ public class PluginMgmtService {
} catch (final Exception e) { } catch (final Exception e) {
LOGGER.log(Level.ERROR, "Refresh plugins failed", e); LOGGER.log(Level.ERROR, "Refresh plugins failed", e);
} }
pluginRepository.setCacheEnabled(true);
} }
/** /**
...@@ -156,7 +167,6 @@ public class PluginMgmtService { ...@@ -156,7 +167,6 @@ public class PluginMgmtService {
public JSONObject setPluginStatus(final String pluginId, final String status) { public JSONObject setPluginStatus(final String pluginId, final String status) {
final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale()); final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale());
final PluginManager pluginManager = PluginManager.getInstance();
final List<AbstractPlugin> plugins = pluginManager.getPlugins(); final List<AbstractPlugin> plugins = pluginManager.getPlugins();
final JSONObject ret = new JSONObject(); final JSONObject ret = new JSONObject();
...@@ -210,7 +220,6 @@ public class PluginMgmtService { ...@@ -210,7 +220,6 @@ public class PluginMgmtService {
final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale()); final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale());
final PluginManager pluginManager = PluginManager.getInstance();
final List<AbstractPlugin> plugins = pluginManager.getPlugins(); final List<AbstractPlugin> plugins = pluginManager.getPlugins();
final JSONObject ret = new JSONObject(); final JSONObject ret = new JSONObject();
......
...@@ -54,6 +54,12 @@ public class PluginQueryService { ...@@ -54,6 +54,12 @@ public class PluginQueryService {
*/ */
@Inject @Inject
private PluginRepository pluginRepository; private PluginRepository pluginRepository;
/**
* Plugin manager.
*/
@Inject
private PluginManager pluginManager;
/** /**
* Gets plugins by the specified request json object. * Gets plugins by the specified request json object.
...@@ -94,7 +100,7 @@ public class PluginQueryService { ...@@ -94,7 +100,7 @@ public class PluginQueryService {
final int windowSize = requestJSONObject.getInt(Pagination.PAGINATION_WINDOW_SIZE); final int windowSize = requestJSONObject.getInt(Pagination.PAGINATION_WINDOW_SIZE);
final List<JSONObject> pluginJSONObjects = new ArrayList<JSONObject>(); final List<JSONObject> pluginJSONObjects = new ArrayList<JSONObject>();
final List<AbstractPlugin> plugins = PluginManager.getInstance().getPlugins(); final List<AbstractPlugin> plugins = pluginManager.getPlugins();
for (final AbstractPlugin plugin : plugins) { for (final AbstractPlugin plugin : plugins) {
final JSONObject jsonObject = plugin.toJSONObject(); final JSONObject jsonObject = plugin.toJSONObject();
...@@ -126,7 +132,7 @@ public class PluginQueryService { ...@@ -126,7 +132,7 @@ public class PluginQueryService {
} }
/** /**
* get the setting(json formatter) of the plugin(from database not cache which does not contains it) by the specified pluginoId. * get the setting(json formatter) of the plugin by the specified pluginoId.
* *
* @param pluginId the specified pluginId * @param pluginId the specified pluginId
* @return the {@link AbstractPlugin} * @return the {@link AbstractPlugin}
......
...@@ -27,8 +27,6 @@ import java.util.Locale; ...@@ -27,8 +27,6 @@ import java.util.Locale;
import java.util.Set; import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import org.b3log.latke.Latkes; import org.b3log.latke.Latkes;
import org.b3log.latke.RuntimeEnv;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.repository.RepositoryException; import org.b3log.latke.repository.RepositoryException;
...@@ -82,12 +80,10 @@ public class PreferenceMgmtService { ...@@ -82,12 +80,10 @@ public class PreferenceMgmtService {
private LangPropsService langPropsService; private LangPropsService langPropsService;
/** /**
* Loads skins for the specified preference and initializes templates * Loads skins for the specified preference and initializes templates loading.
* loading.
* *
* <p> * <p>
* If the skins directory has been changed, persists the change into * If the skins directory has been changed, persists the change into preference.
* preference.
* </p> * </p>
* *
* @param preference the specified preference * @param preference the specified preference
...@@ -109,6 +105,7 @@ public class PreferenceMgmtService { ...@@ -109,6 +105,7 @@ public class PreferenceMgmtService {
if (null == name) { if (null == name) {
LOGGER.log(Level.WARN, "The directory[{0}] does not contain any skin, ignored it", dirName); LOGGER.log(Level.WARN, "The directory[{0}] does not contain any skin, ignored it", dirName);
continue; continue;
} }
...@@ -130,15 +127,13 @@ public class PreferenceMgmtService { ...@@ -130,15 +127,13 @@ public class PreferenceMgmtService {
LOGGER.log(Level.ERROR, "Can not find skin[dirName=ease]"); LOGGER.log(Level.ERROR, "Can not find skin[dirName=ease]");
throw new IllegalStateException( throw new IllegalStateException(
"Can not find default skin[dirName=ease], please redeploy your B3log Solo and make sure " "Can not find default skin[dirName=ease], please redeploy your B3log Solo and make sure contains this default skin!");
+ "contains this default skin!");
} }
preference.put(SKIN_DIR_NAME, "ease"); preference.put(SKIN_DIR_NAME, "ease");
preference.put(SKIN_NAME, "ease"); preference.put(SKIN_NAME, "ease");
updatePreference(preference); updatePreference(preference);
PageCaches.removeAll(); // Clears cache manually.
} }
final String skinsString = skinArray.toString(); final String skinsString = skinArray.toString();
...@@ -147,20 +142,6 @@ public class PreferenceMgmtService { ...@@ -147,20 +142,6 @@ public class PreferenceMgmtService {
LOGGER.log(Level.INFO, "The skins directory has been changed, persists " + "the change into preference"); LOGGER.log(Level.INFO, "The skins directory has been changed, persists " + "the change into preference");
preference.put(SKINS, skinsString); preference.put(SKINS, skinsString);
updatePreference(preference); updatePreference(preference);
PageCaches.removeAll(); // Clears cache manually.
}
boolean prefsPageCacheEnabled = preference.getBoolean(Preference.PAGE_CACHE_ENABLED);
if (!Latkes.isPageCacheEnabled() && prefsPageCacheEnabled) {
preference.put(Preference.PAGE_CACHE_ENABLED, false);
}
prefsPageCacheEnabled = preference.getBoolean(Preference.PAGE_CACHE_ENABLED);
if (prefsPageCacheEnabled) {
Latkes.enablePageCache();
} else {
Latkes.disablePageCache();
} }
setDirectoryForTemplateLoading(preference.getString(SKIN_DIR_NAME)); setDirectoryForTemplateLoading(preference.getString(SKIN_DIR_NAME));
...@@ -177,11 +158,9 @@ public class PreferenceMgmtService { ...@@ -177,11 +158,9 @@ public class PreferenceMgmtService {
} }
/** /**
* Updates the reply notification template with the specified reply * Updates the reply notification template with the specified reply notification template.
* notification template.
* *
* @param replyNotificationTemplate the specified reply notification * @param replyNotificationTemplate the specified reply notification template
* template
* @throws ServiceException service exception * @throws ServiceException service exception
*/ */
public void updateReplyNotificationTemplate(final JSONObject replyNotificationTemplate) throws ServiceException { public void updateReplyNotificationTemplate(final JSONObject replyNotificationTemplate) throws ServiceException {
...@@ -218,8 +197,6 @@ public class PreferenceMgmtService { ...@@ -218,8 +197,6 @@ public class PreferenceMgmtService {
} }
} }
// TODO: checks preference
final Transaction transaction = preferenceRepository.beginTransaction(); final Transaction transaction = preferenceRepository.beginTransaction();
try { try {
...@@ -244,7 +221,6 @@ public class PreferenceMgmtService { ...@@ -244,7 +221,6 @@ public class PreferenceMgmtService {
final String skinPath = webRootPath + Skin.SKINS + "/" + skinDirName; final String skinPath = webRootPath + Skin.SKINS + "/" + skinDirName;
LOGGER.log(Level.DEBUG, "Skin path[{0}]", skinPath); LOGGER.log(Level.DEBUG, "Skin path[{0}]", skinPath);
Templates.CACHE.clear();
preference.put(Skin.SKINS, skinArray.toString()); preference.put(Skin.SKINS, skinArray.toString());
...@@ -259,26 +235,6 @@ public class PreferenceMgmtService { ...@@ -259,26 +235,6 @@ public class PreferenceMgmtService {
preference.put(ADMIN_EMAIL, adminEmail); preference.put(ADMIN_EMAIL, adminEmail);
if (!preference.has(PAGE_CACHE_ENABLED)) {
preference.put(PAGE_CACHE_ENABLED, oldPreference.getBoolean(PAGE_CACHE_ENABLED));
} else {
if (RuntimeEnv.BAE == Latkes.getRuntimeEnv()) {
// XXX: Ignores user's setting, uses default
// https://github.com/b3log/b3log-solo/issues/73
preference.put(PAGE_CACHE_ENABLED, Default.DEFAULT_PAGE_CACHE_ENABLED);
}
}
final String maxPageCntStr = Latkes.getMaxPageCacheCnt();
if (Integer.valueOf(maxPageCntStr) <= 0) {
preference.put(PAGE_CACHE_ENABLED, false);
}
final boolean pageCacheEnabled = preference.getBoolean(Preference.PAGE_CACHE_ENABLED);
Templates.enableCache(pageCacheEnabled);
final String version = oldPreference.optString(VERSION); final String version = oldPreference.optString(VERSION);
if (!Strings.isEmptyOrNull(version)) { if (!Strings.isEmptyOrNull(version)) {
...@@ -295,12 +251,6 @@ public class PreferenceMgmtService { ...@@ -295,12 +251,6 @@ public class PreferenceMgmtService {
transaction.commit(); transaction.commit();
Templates.MAIN_CFG.setDirectoryForTemplateLoading(new File(skinPath)); Templates.MAIN_CFG.setDirectoryForTemplateLoading(new File(skinPath));
if (preference.getBoolean(PAGE_CACHE_ENABLED)) {
Latkes.enablePageCache();
} else {
Latkes.disablePageCache();
}
} catch (final JSONException e) { } catch (final JSONException e) {
if (transaction.isActive()) { if (transaction.isActive()) {
transaction.rollback(); transaction.rollback();
......
...@@ -16,18 +16,12 @@ ...@@ -16,18 +16,12 @@
package org.b3log.solo.service; package org.b3log.solo.service;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.b3log.latke.Latkes;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.repository.RepositoryException; import org.b3log.latke.repository.RepositoryException;
...@@ -35,10 +29,7 @@ import org.b3log.latke.repository.Transaction; ...@@ -35,10 +29,7 @@ import org.b3log.latke.repository.Transaction;
import org.b3log.latke.service.LangPropsService; import org.b3log.latke.service.LangPropsService;
import org.b3log.latke.service.ServiceException; import org.b3log.latke.service.ServiceException;
import org.b3log.latke.service.annotation.Service; import org.b3log.latke.service.annotation.Service;
import org.b3log.latke.util.CollectionUtils;
import org.b3log.latke.util.Requests; import org.b3log.latke.util.Requests;
import org.b3log.solo.model.Article;
import org.b3log.solo.model.PageTypes;
import org.json.JSONObject; import org.json.JSONObject;
import org.b3log.solo.model.Statistic; import org.b3log.solo.model.Statistic;
import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.repository.ArticleRepository;
...@@ -71,11 +62,6 @@ public class StatisticMgmtService { ...@@ -71,11 +62,6 @@ public class StatisticMgmtService {
@Inject @Inject
private StatisticRepository statisticRepository; private StatisticRepository statisticRepository;
/**
* Flush size.
*/
private static final int FLUSH_SIZE = 30;
/** /**
* Language service. * Language service.
*/ */
...@@ -88,11 +74,6 @@ public class StatisticMgmtService { ...@@ -88,11 +74,6 @@ public class StatisticMgmtService {
@Inject @Inject
private ArticleRepository articleRepository; private ArticleRepository articleRepository;
/**
* Repository cache prefix, refers to GAERepository#CACHE_KEY_PREFIX.
*/
public static final String REPOSITORY_CACHE_KEY_PREFIX = "repository";
/** /**
* Online visitor cache. * Online visitor cache.
* *
...@@ -147,23 +128,18 @@ public class StatisticMgmtService { ...@@ -147,23 +128,18 @@ public class StatisticMgmtService {
++blogViewCnt; ++blogViewCnt;
statistic.put(Statistic.STATISTIC_BLOG_VIEW_COUNT, blogViewCnt); statistic.put(Statistic.STATISTIC_BLOG_VIEW_COUNT, blogViewCnt);
if (!Latkes.isDataCacheEnabled()) { final Transaction transaction = statisticRepository.beginTransaction();
final Transaction transaction = statisticRepository.beginTransaction();
try {
statisticRepository.update(Statistic.STATISTIC, statistic);
transaction.commit(); try {
} catch (final RepositoryException e) { statisticRepository.update(Statistic.STATISTIC, statistic);
if (transaction.isActive()) {
transaction.rollback();
}
LOGGER.log(Level.ERROR, "Updates blog view count failed", e); transaction.commit();
} catch (final RepositoryException e) {
if (transaction.isActive()) {
transaction.rollback();
} }
} else {
// Repository cache prefix, Refers to GAERepository#CACHE_KEY_PREFIX LOGGER.log(Level.ERROR, "Updates blog view count failed", e);
statisticRepository.getCache().putAsync(REPOSITORY_CACHE_KEY_PREFIX + Statistic.STATISTIC, statistic);
} }
LOGGER.log(Level.DEBUG, "Inced blog view count[statistic={0}]", statistic); LOGGER.log(Level.DEBUG, "Inced blog view count[statistic={0}]", statistic);
...@@ -373,98 +349,6 @@ public class StatisticMgmtService { ...@@ -373,98 +349,6 @@ public class StatisticMgmtService {
LOGGER.log(Level.DEBUG, "Current online visitor count [{0}]", ONLINE_VISITORS.size()); LOGGER.log(Level.DEBUG, "Current online visitor count [{0}]", ONLINE_VISITORS.size());
} }
/**
* Flushes the statistic to repository.
*
* @throws ServiceException
*/
public void flushStatistic() throws ServiceException {
if (!Latkes.isDataCacheEnabled()) {
return;
}
final JSONObject statistic = (JSONObject) statisticRepository.getCache().get(REPOSITORY_CACHE_KEY_PREFIX + Statistic.STATISTIC);
if (null == statistic) {
LOGGER.log(Level.INFO, "Not found statistic in cache, ignores sync");
return;
}
final Transaction transaction = statisticRepository.beginTransaction();
transaction.clearQueryCache(false);
try {
statisticRepository.getCache().remove(REPOSITORY_CACHE_KEY_PREFIX + Statistic.STATISTIC);
// For blog view counter
statisticRepository.update(Statistic.STATISTIC, statistic);
// For article view counter
final Set<String> keys = PageCaches.getKeys();
final List<String> keyList = new ArrayList<String>(keys);
final int size = keys.size() > FLUSH_SIZE ? FLUSH_SIZE : keys.size(); // Flush FLUSH_SIZE articles at most
final List<Integer> idx = CollectionUtils.getRandomIntegers(0, keys.size(), size);
final Set<String> cachedPageKeys = new HashSet<String>();
for (final Integer i : idx) {
cachedPageKeys.add(keyList.get(i));
}
for (final String cachedPageKey : cachedPageKeys) {
final JSONObject cachedPage = PageCaches.get(cachedPageKey);
if (null == cachedPage) {
continue;
}
final Map<String, String> langs = langPropsService.getAll(Latkes.getLocale());
if (!cachedPage.optString(PageCaches.CACHED_TYPE).equals(langs.get(PageTypes.ARTICLE.getLangeLabel()))) { // Cached is not an article page
continue;
}
final int hitCount = cachedPage.optInt(PageCaches.CACHED_HIT_COUNT);
final String articleId = cachedPage.optString(PageCaches.CACHED_OID);
final JSONObject article = articleRepository.get(articleId);
if (null == article) {
continue;
}
LOGGER.log(Level.DEBUG, "Updating article[id={0}, title={1}] view count",
new Object[] {articleId, cachedPage.optString(PageCaches.CACHED_TITLE)});
final int oldViewCount = article.optInt(Article.ARTICLE_VIEW_COUNT);
final int viewCount = oldViewCount + hitCount;
article.put(Article.ARTICLE_VIEW_COUNT, viewCount);
article.put(Article.ARTICLE_RANDOM_DOUBLE, Math.random()); // Updates random value
articleRepository.update(articleId, article);
cachedPage.put(PageCaches.CACHED_HIT_COUNT, 0);
LOGGER.log(Level.DEBUG, "Updating article[id={0}, title={1}] view count from [{2}] to [{3}]",
new Object[] {articleId, article.optString(Article.ARTICLE_TITLE), oldViewCount, viewCount});
}
transaction.commit();
LOGGER.log(Level.INFO, "Synchronized statistic from cache to repository[statistic={0}]", statistic);
} catch (final RepositoryException e) {
if (transaction.isActive()) {
transaction.rollback();
}
LOGGER.log(Level.ERROR, "Updates statistic failed", e);
}
}
/** /**
* Updates the statistic with the specified statistic. * Updates the statistic with the specified statistic.
* *
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
package org.b3log.solo.util; package org.b3log.solo.util;
import java.util.Date;
import java.util.TimeZone; import java.util.TimeZone;
import org.b3log.latke.util.freemarker.Templates; import org.b3log.latke.util.freemarker.Templates;
...@@ -25,28 +24,10 @@ import org.b3log.latke.util.freemarker.Templates; ...@@ -25,28 +24,10 @@ import org.b3log.latke.util.freemarker.Templates;
* Time zone utilities. * Time zone utilities.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.4, Jan 18, 2013 * @version 1.0.0.5, Oct 30, 2013
*/ */
public final class TimeZones { public final class TimeZones {
/**
* Gets the current date with the specified time zone id.
*
* @param timeZoneId the specified time zone id
* @return date
*/
public static Date getTime(final String timeZoneId) {
final TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);
final TimeZone defaultTimeZone = TimeZone.getDefault();
TimeZone.setDefault(timeZone);
final Date ret = new Date();
TimeZone.setDefault(defaultTimeZone);
return ret;
}
/** /**
* Sets time zone by the specified time zone id. * Sets time zone by the specified time zone id.
* *
......
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
...@@ -41,27 +41,21 @@ public class ArchiveDateArticleRepositoryImplTestCase extends AbstractTestCase { ...@@ -41,27 +41,21 @@ public class ArchiveDateArticleRepositoryImplTestCase extends AbstractTestCase {
*/ */
@Test @Test
public void add() throws Exception { public void add() throws Exception {
final ArchiveDateArticleRepository archiveDateArticleRepository = final ArchiveDateArticleRepository archiveDateArticleRepository = getArchiveDateArticleRepository();
getArchiveDateArticleRepository();
final JSONObject archiveDateArticle = new JSONObject(); final JSONObject archiveDateArticle = new JSONObject();
archiveDateArticle.put(ArchiveDate.ARCHIVE_DATE + "_" archiveDateArticle.put(ArchiveDate.ARCHIVE_DATE + "_" + Keys.OBJECT_ID, "archiveDateId");
+ Keys.OBJECT_ID, "archiveDateId"); archiveDateArticle.put(Article.ARTICLE + "_" + Keys.OBJECT_ID, "articleId");
archiveDateArticle.put(Article.ARTICLE + "_"
+ Keys.OBJECT_ID, "articleId");
final Transaction transaction = archiveDateArticleRepository. final Transaction transaction = archiveDateArticleRepository.beginTransaction();
beginTransaction();
archiveDateArticleRepository.add(archiveDateArticle); archiveDateArticleRepository.add(archiveDateArticle);
transaction.commit(); transaction.commit();
final JSONObject found = final JSONObject found = archiveDateArticleRepository.getByArticleId("articleId");
archiveDateArticleRepository.getByArticleId("articleId");
Assert.assertNotNull(found); Assert.assertNotNull(found);
final JSONObject notFound = final JSONObject notFound = archiveDateArticleRepository.getByArticleId("not found");
archiveDateArticleRepository.getByArticleId("not found");
Assert.assertNull(notFound); Assert.assertNull(notFound);
} }
......
...@@ -51,9 +51,5 @@ cache=GAE ...@@ -51,9 +51,5 @@ cache=GAE
# userService=GAE # userService=GAE
userService=LOCAL userService=LOCAL
#### Cache ####
cache.maxPageCnt=128
cache.maxDataCnt=128
#### Static resource version #### #### Static resource version ####
staticResourceVersion=201206280945 staticResourceVersion=201206280945
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Description: B3log Solo parent POM. Description: B3log Solo parent POM.
Version: 2.0.3.2, Aug 20, 2013 Version: 2.0.3.3, Oct 29, 2013
Author: Liang Ding Author: Liang Ding
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<groupId>org.b3log</groupId> <groupId>org.b3log</groupId>
<artifactId>solo</artifactId> <artifactId>solo</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>0.6.1</version> <version>0.6.5</version>
<name>B3log Solo</name> <name>B3log Solo</name>
<url>https://github.com/b3log/b3log-solo</url> <url>https://github.com/b3log/b3log-solo</url>
<description> <description>
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Description: B3log Solo BAE POM. Description: B3log Solo BAE POM.
Version: 1.0.1.5, Aug 24, 2013 Version: 1.0.1.6, Oct 29, 2013
Author: Liang Ding Author: Liang Ding
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.b3log</groupId> <groupId>org.b3log</groupId>
<artifactId>solo-war</artifactId> <artifactId>solo-war</artifactId>
<version>0.6.1</version> <version>0.6.5</version>
</parent> </parent>
<properties> <properties>
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# #
# Description: B3log Latke configurations. Configures the section "Server" carefully. # Description: B3log Latke configurations. Configures the section "Server" carefully.
# Version: 1.0.1.1, Aug 24, 2013 # Version: 1.0.1.2, Oct 31, 2013
# Author: Liang Ding # Author: Liang Ding
# #
...@@ -41,8 +41,8 @@ scanPath=org.b3log.solo ...@@ -41,8 +41,8 @@ scanPath=org.b3log.solo
runtimeEnv=BAE runtimeEnv=BAE
#### Runtime Mode #### #### Runtime Mode ####
#runtimeMode=DEVELOPMENT runtimeMode=DEVELOPMENT
runtimeMode=PRODUCTION #runtimeMode=PRODUCTION
#### Cache Implementation #### #### Cache Implementation ####
# Note: If the runtime environment is LOCAL, the cache will be 'LOCAL' always # Note: If the runtime environment is LOCAL, the cache will be 'LOCAL' always
...@@ -52,9 +52,5 @@ cache=BAE ...@@ -52,9 +52,5 @@ cache=BAE
#### User Service Implementation #### #### User Service Implementation ####
userService=LOCAL userService=LOCAL
#### Cache ####
cache.maxPageCnt=0
cache.maxDataCnt=0
#### Static resource version #### #### Static resource version ####
staticResourceVersion=201308241630 staticResourceVersion=201310311200
\ No newline at end of file \ No newline at end of file
...@@ -15,12 +15,12 @@ ...@@ -15,12 +15,12 @@
# #
# #
# Description: B3log Solo logging configurations. # Description: B3log Solo logging configurations for BAE.
# Version: 1.0.0.0, Aug 24, 2013 # Version: 1.0.0.2, Oct 29, 2013
# Author: Liang Ding # Author: Liang Ding
# #
log4j.rootLogger=INFO, stdout, bae log4j.rootLogger=WARN, stdout, bae
log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out log4j.appender.stdout.Target=System.out
...@@ -31,7 +31,8 @@ log4j.appender.bae=com.baidu.bae.api.baelog.BaeAppender ...@@ -31,7 +31,8 @@ log4j.appender.bae=com.baidu.bae.api.baelog.BaeAppender
log4j.appender.bae.layout=org.apache.log4j.PatternLayout log4j.appender.bae.layout=org.apache.log4j.PatternLayout
log4j.appender.bae.layout.ConversionPattern=[%-5p]-[%d{yyyy-MM-dd HH:mm:ss}]-[%c:%L]: %m%n log4j.appender.bae.layout.ConversionPattern=[%-5p]-[%d{yyyy-MM-dd HH:mm:ss}]-[%c:%L]: %m%n
log4j.logger.org.b3log.solo=DEBUG log4j.logger.org.b3log.solo=WARN
log4j.logger.org.b3log.latke=INFO log4j.logger.org.b3log.latke=ERROR
log4j.logger.org.b3log.latke.util.freemarker.Templates=ERROR
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Description: B3log Solo GAE POM. Description: B3log Solo GAE POM.
Version: 2.0.2.3, Aug 20, 2013 Version: 2.0.2.4, Oct 29, 2013
Author: Liang Ding Author: Liang Ding
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.b3log</groupId> <groupId>org.b3log</groupId>
<artifactId>solo-war</artifactId> <artifactId>solo-war</artifactId>
<version>0.6.1</version> <version>0.6.5</version>
</parent> </parent>
<properties> <properties>
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# #
# Description: B3log Latke configurations. Configures the section "Server" carefully. # Description: B3log Latke configurations. Configures the section "Server" carefully.
# Version: 1.0.0.9, Aug 24, 2013 # Version: 1.0.1.0, Oct 31, 2013
# Author: Liang Ding # Author: Liang Ding
# #
...@@ -41,8 +41,8 @@ scanPath=org.b3log.solo ...@@ -41,8 +41,8 @@ scanPath=org.b3log.solo
runtimeEnv=GAE runtimeEnv=GAE
#### Runtime Mode #### #### Runtime Mode ####
#runtimeMode=DEVELOPMENT runtimeMode=DEVELOPMENT
runtimeMode=PRODUCTION #runtimeMode=PRODUCTION
#### Cache Implementation #### #### Cache Implementation ####
# Note: If the runtime environment is LOCAL, the cache will be 'LOCAL' always # Note: If the runtime environment is LOCAL, the cache will be 'LOCAL' always
...@@ -51,9 +51,5 @@ cache=GAE ...@@ -51,9 +51,5 @@ cache=GAE
#### User Service Implementation #### #### User Service Implementation ####
userService=LOCAL userService=LOCAL
#### Cache ####
cache.maxPageCnt=1024000
cache.maxDataCnt=1024000
#### Static resource version #### #### Static resource version ####
staticResourceVersion=201308241630 staticResourceVersion=201310311200
\ No newline at end of file \ No newline at end of file
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
# <system-properties> # <system-properties>
# <property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties"/> # <property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties"/>
# </system-properties> # </system-properties>
# Version: 1.0.2.1, Jun 4, 2013 # Version: 1.0.2.2, Oct 29, 2013
# Author: Liang Ding # Author: Liang Ding
# #
...@@ -27,14 +27,10 @@ handlers=java.util.logging.ConsoleHandler ...@@ -27,14 +27,10 @@ handlers=java.util.logging.ConsoleHandler
org.b3log.solo.level=INFO org.b3log.solo.level=INFO
org.b3log.latke.level=WARNING org.b3log.latke.level=SEVERE
org.b3log.latke.util.freemarker.Templates.level=SEVERE org.b3log.latke.util.freemarker.Templates.level=SEVERE
org.b3log.latke.cache.level=WARNING
org.b3log.latke.repository.jdbc.level=WARNING
com.google.level=WARNING com.google.level=WARNING
com.sun.level=WARNING com.sun.level=WARNING
freemarker.level=WARNING freemarker.level=WARNING
org.apache.level=WARNING org.apache.level=WARNING
# c3p0
com.mchange.level=WARNING
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Description: B3log Solo (H2) standard Servlet container POM. Description: B3log Solo (H2) standard Servlet container POM.
Version: 1.0.0.2, Aug 20, 2013 Version: 1.0.0.3, Oct 29, 2013
Author: Liang Ding Author: Liang Ding
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.b3log</groupId> <groupId>org.b3log</groupId>
<artifactId>solo-war</artifactId> <artifactId>solo-war</artifactId>
<version>0.6.1</version> <version>0.6.5</version>
</parent> </parent>
<properties> <properties>
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# #
# Description: B3log Latke configurations. Configures the section "Server" carefully. # Description: B3log Latke configurations. Configures the section "Server" carefully.
# Version: 1.0.0.9, Aug 24, 2013 # Version: 1.0.1.0, Oct 31, 2013
# Author: Liang Ding # Author: Liang Ding
# #
...@@ -41,8 +41,8 @@ scanPath=org.b3log.solo ...@@ -41,8 +41,8 @@ scanPath=org.b3log.solo
runtimeEnv=LOCAL runtimeEnv=LOCAL
#### Runtime Mode #### #### Runtime Mode ####
#runtimeMode=DEVELOPMENT #runtimeMode=PRODUCTION
runtimeMode=PRODUCTION runtimeMode=DEVELOPMENT
#### Cache Implementation #### #### Cache Implementation ####
# Note: If the runtime environment is LOCAL, the cache will be 'LOCAL' always # Note: If the runtime environment is LOCAL, the cache will be 'LOCAL' always
...@@ -51,9 +51,5 @@ cache=LOCAL ...@@ -51,9 +51,5 @@ cache=LOCAL
#### User Service Implementation #### #### User Service Implementation ####
userService=LOCAL userService=LOCAL
#### Cache ####
cache.maxPageCnt=128
cache.maxDataCnt=128
#### Static resource version #### #### Static resource version ####
staticResourceVersion=201308241630 staticResourceVersion=201310311200
\ No newline at end of file \ No newline at end of file
...@@ -42,5 +42,5 @@ jdbc.maxConnCnt=10 ...@@ -42,5 +42,5 @@ jdbc.maxConnCnt=10
jdbc.transactionIsolation=READ_COMMITTED jdbc.transactionIsolation=READ_COMMITTED
# The specific table name prefix # The specific table name prefix
jdbc.tablePrefix= jdbc.tablePrefix=b3_solo
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Description: B3log Solo (MySQL) standard Servlet container POM. Description: B3log Solo (MySQL) standard Servlet container POM.
Version: 1.0.1.3, Aug 20, 2013 Version: 1.0.1.4, Oct 29, 2013
Author: Liang Ding Author: Liang Ding
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.b3log</groupId> <groupId>org.b3log</groupId>
<artifactId>solo-war</artifactId> <artifactId>solo-war</artifactId>
<version>0.6.1</version> <version>0.6.5</version>
</parent> </parent>
<properties> <properties>
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# #
# Description: B3log Latke configurations. Configures the section "Server" carefully. # Description: B3log Latke configurations. Configures the section "Server" carefully.
# Version: 1.0.0.9, Aug 24, 2013 # Version: 1.0.1.0, Oct 31, 2013
# Author: Liang Ding # Author: Liang Ding
# #
...@@ -41,8 +41,8 @@ scanPath=org.b3log.solo ...@@ -41,8 +41,8 @@ scanPath=org.b3log.solo
runtimeEnv=LOCAL runtimeEnv=LOCAL
#### Runtime Mode #### #### Runtime Mode ####
#runtimeMode=DEVELOPMENT runtimeMode=DEVELOPMENT
runtimeMode=PRODUCTION #runtimeMode=PRODUCTION
#### Cache Implementation #### #### Cache Implementation ####
# Note: If the runtime environment is LOCAL, the cache will be 'LOCAL' always # Note: If the runtime environment is LOCAL, the cache will be 'LOCAL' always
...@@ -51,9 +51,5 @@ cache=LOCAL ...@@ -51,9 +51,5 @@ cache=LOCAL
#### User Service Implementation #### #### User Service Implementation ####
userService=LOCAL userService=LOCAL
#### Cache ####
cache.maxPageCnt=128
cache.maxDataCnt=128
#### Static resource version #### #### Static resource version ####
staticResourceVersion=201308241630 staticResourceVersion=201310311200
\ No newline at end of file \ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Description: B3log Solo WAR POM. Description: B3log Solo WAR POM.
Version: 2.0.1.7, Aug 20, 2013 Version: 2.0.1.8, Oct 29, 2013
Author: Liang Ding Author: Liang Ding
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.b3log</groupId> <groupId>org.b3log</groupId>
<artifactId>solo</artifactId> <artifactId>solo</artifactId>
<version>0.6.1</version> <version>0.6.5</version>
</parent> </parent>
<modules> <modules>
...@@ -62,8 +62,13 @@ ...@@ -62,8 +62,13 @@
<artifactId>maven-jetty-plugin</artifactId> <artifactId>maven-jetty-plugin</artifactId>
<version>6.1.22</version> <version>6.1.22</version>
<configuration> <configuration>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>8080</port>
</connector>
</connectors>
<stopKey>stop</stopKey> <stopKey>stop</stopKey>
<stopPort>4500</stopPort> <stopPort>4502</stopPort>
<webAppSourceDirectory>../src/main/webapp</webAppSourceDirectory> <webAppSourceDirectory>../src/main/webapp</webAppSourceDirectory>
<classesDirectory>${basedir}/target/${project.build.finalName}/WEB-INF/classes</classesDirectory> <classesDirectory>${basedir}/target/${project.build.finalName}/WEB-INF/classes</classesDirectory>
<contextPath>/</contextPath> <contextPath>/</contextPath>
......
...@@ -231,8 +231,6 @@ tagsLabel=Tags ...@@ -231,8 +231,6 @@ tagsLabel=Tags
importedLabel=Imported importedLabel=Imported
captcha1Label=Captcha: captcha1Label=Captcha:
captchaLabel=Captcha captchaLabel=Captcha
clearAllCacheLabel=Clear all cache
clearCacheLabel=Clear cache
indexLabel=Index indexLabel=Index
nextArticle1Label=Next: nextArticle1Label=Next:
previousArticle1Label=Previous: previousArticle1Label=Previous:
......
...@@ -231,8 +231,6 @@ tagsLabel=\u6807\u7b7e ...@@ -231,8 +231,6 @@ tagsLabel=\u6807\u7b7e
importedLabel=\u5df2\u5bfc\u5165 importedLabel=\u5df2\u5bfc\u5165
captcha1Label=\u9a8c\u8bc1\u7801\uff1a captcha1Label=\u9a8c\u8bc1\u7801\uff1a
captchaLabel=\u9a8c\u8bc1\u7801 captchaLabel=\u9a8c\u8bc1\u7801
clearAllCacheLabel=\u6e05\u9664\u6240\u6709\u9875\u9762\u7f13\u5b58
clearCacheLabel=\u6e05\u9664\u672c\u9875\u7f13\u5b58
indexLabel=\u9996\u9875 indexLabel=\u9996\u9875
nextArticle1Label=\u65b0\u4e00\u7bc7\uff1a nextArticle1Label=\u65b0\u4e00\u7bc7\uff1a
previousArticle1Label=\u65e7\u4e00\u7bc7\uff1a previousArticle1Label=\u65e7\u4e00\u7bc7\uff1a
......
...@@ -16,18 +16,19 @@ ...@@ -16,18 +16,19 @@
# #
# Description: B3log Solo logging configurations. # Description: B3log Solo logging configurations.
# Version: 1.0.0.0, Jun 19, 2013 # Version: 1.0.0.2, Oct 29, 2013
# Author: Liang Ding # Author: Liang Ding
# #
log4j.rootLogger=INFO, stdout log4j.rootLogger=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%-5p]-[%d{yyyy-MM-dd HH:mm:ss}]-[%c:%L]: %m%n log4j.appender.stdout.layout.ConversionPattern=[%-5p]-[%d{yyyy-MM-dd HH:mm:ss}]-[%c:%L]: %m%n
log4j.logger.org.b3log.solo=DEBUG log4j.logger.org.b3log.solo=WARN
log4j.logger.org.b3log.latke=DEBUG log4j.logger.org.b3log.latke=ERROR
log4j.logger.org.b3log.latke.util.freemarker.Templates=ERROR
...@@ -5,6 +5,21 @@ ...@@ -5,6 +5,21 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head> </head>
<body> <body>
<h2>Release 0.6.5 - Nov 1, 2013</h2>
<ul>
<li><a href="https://github.com/b3log/b3log-solo/issues/282">282 找回密码问题</a>&nbsp;<span style='background: #fc2929 !important;color:#FFFFFF !important;padding: 1px 4px;'>bug</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/283">283 社区同步评论</a>&nbsp;<span style='background: #fc2929 !important;color:#FFFFFF !important;padding: 1px 4px;'>bug</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/288">288 IoC 容器冲突</a>&nbsp;<span style='background: #fc2929 !important;color:#FFFFFF !important;padding: 1px 4px;'>bug</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/294">294 发布文章时允许评论开关问题</a>&nbsp;<span style='background: #fc2929 !important;color:#FFFFFF !important;padding: 1px 4px;'>bug</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/296">296 数据恢复接口被过滤器跳过</a>&nbsp;<span style='background: #fc2929 !important;color:#FFFFFF !important;padding: 1px 4px;'>bug</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/302">302 更新已发布文章问题</a>&nbsp;<span style='background: #fc2929 !important;color:#FFFFFF !important;padding: 1px 4px;'>bug</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/295">295 未初始化时启动日志报错</a>&nbsp;<span style='background: #84b6eb !important;color:#FFFFFF !important;padding: 1px 4px;'>enhancement</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/299">299 评论信息填充优化</a>&nbsp;<span style='background: #84b6eb !important;color:#FFFFFF !important;padding: 1px 4px;'>enhancement</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/316">316 评论开关页面显示</a>&nbsp;<span style='background: #84b6eb !important;color:#FFFFFF !important;padding: 1px 4px;'>enhancement</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/317">317 自动保存文章时间间隔</a>&nbsp;<span style='background: #84b6eb !important;color:#FFFFFF !important;padding: 1px 4px;'>enhancement</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/318">318 去缓存</a>&nbsp;<span style='background: #84b6eb !important;color:#FFFFFF !important;padding: 1px 4px;'>enhancement</span></li>
<li><a href="https://github.com/b3log/b3log-solo/issues/320">320 加入登录状态模版变量</a>&nbsp;<span style='background: #84b6eb !important;color:#FFFFFF !important;padding: 1px 4px;'>enhancement</span></li>
</ul>
<h2>Release 0.6.1 - Aug 25, 2013</h2> <h2>Release 0.6.1 - Aug 25, 2013</h2>
<ul> <ul>
<li><a href="https://github.com/b3log/b3log-solo/issues/200">200 找回密码</a>&nbsp;<span style='background: #02e10c !important;color:#FFFFFF !important;padding: 1px 4px;'>feature</span></li> <li><a href="https://github.com/b3log/b3log-solo/issues/200">200 找回密码</a>&nbsp;<span style='background: #02e10c !important;color:#FFFFFF !important;padding: 1px 4px;'>feature</span></li>
......
...@@ -20,12 +20,12 @@ ...@@ -20,12 +20,12 @@
Description: Web deployment descriptor on GAE. See Description: Web deployment descriptor on GAE. See
http://code.google.com/intl/en/appengine/docs/java/config/appconfig.html http://code.google.com/intl/en/appengine/docs/java/config/appconfig.html
for more details. for more details.
Version: 1.0.4.3, Aug 24, 2013 Version: 1.0.4.4, Oct 31, 2013
Author: Liang Ding Author: Liang Ding
--> -->
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>solo-demo</application> <application>solo-demo</application>
<version>061</version> <version>065</version>
<sessions-enabled>true</sessions-enabled> <sessions-enabled>true</sessions-enabled>
......
...@@ -31,12 +31,6 @@ ...@@ -31,12 +31,6 @@
<schedule>every 5 minutes</schedule> <schedule>every 5 minutes</schedule>
</cron> </cron>
<cron>
<url>/console/stat/viewcnt</url>
<description>Async Blog/Article counter</description>
<schedule>every 30 minutes</schedule>
</cron>
<cron> <cron>
<url>/console/stat/onlineVisitorRefresh</url> <url>/console/stat/onlineVisitorRefresh</url>
<description>Online Visitor Refresher</description> <description>Online Visitor Refresher</description>
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
--> -->
<!-- <!--
Description: B3log Solo web deployment descriptor. Description: B3log Solo web deployment descriptor.
Version: 1.0.5.0, Jan 25, 2013 Version: 1.0.5.1, Sep 27, 2013
Author: Liang Ding Author: Liang Ding
--> -->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
...@@ -65,14 +65,6 @@ ...@@ -65,14 +65,6 @@
<url-pattern>/rm-all-data.do</url-pattern> <url-pattern>/rm-all-data.do</url-pattern>
<url-pattern>/fix/*</url-pattern> <url-pattern>/fix/*</url-pattern>
</filter-mapping> </filter-mapping>
<filter>
<filter-name>PageCacheFilter</filter-name>
<filter-class>org.b3log.solo.filter.PageCacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PageCacheFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter> <filter>
<filter-name>PermalinkFilter</filter-name> <filter-name>PermalinkFilter</filter-name>
<filter-class>org.b3log.solo.filter.PermalinkFilter</filter-class> <filter-class>org.b3log.solo.filter.PermalinkFilter</filter-class>
...@@ -97,12 +89,12 @@ ...@@ -97,12 +89,12 @@
</session-config> </session-config>
<servlet> <servlet>
<servlet-name>HTTPRequestDispatcher</servlet-name> <servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.b3log.latke.servlet.HTTPRequestDispatcher</servlet-class> <servlet-class>org.b3log.latke.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup> <load-on-startup>2</load-on-startup>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>
<servlet-name>HTTPRequestDispatcher</servlet-name> <servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/*</url-pattern> <url-pattern>/*</url-pattern>
</servlet-mapping> </servlet-mapping>
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>${articleViewPwdLabel}</title> <title>${articleViewPwdLabel}</title>
<meta name="keywords" content="GAE 博客,GAE blog,b3log" /> <meta name="keywords" content="Java 博客,GAE blog,b3log" />
<meta name="description" content="An open source blog based on GAE Java,GAE Java 开源博客" /> <meta name="description" content="An open source blog based on GAE Java,GAE Java 开源博客" />
<meta name="owner" content="B3log Team" /> <meta name="owner" content="B3log Team" />
<meta name="author" content="B3log Team" /> <meta name="author" content="B3log Team" />
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* 403, 404, 500, article-pwd, init, login and kill-browser page style. * 403, 404, 500, article-pwd, init, login and kill-browser page style.
* *
* @author <a href="mailto:LLY219@gmail.com">Liyuan Li</a> * @author <a href="mailto:LLY219@gmail.com">Liyuan Li</a>
* @version 1.0.1.5, May 30, 2013 * @version 1.0.1.6, Sep 12, 2013
*/ */
html { html {
height: 100%; height: 100%;
...@@ -269,6 +269,10 @@ button:active { ...@@ -269,6 +269,10 @@ button:active {
width: 470px; width: 470px;
} }
#init .form {
padding: 10px 20px;
}
#init input, #init input,
.register input { .register input {
margin: 5px 0; margin: 5px 0;
...@@ -280,7 +284,7 @@ button:active { ...@@ -280,7 +284,7 @@ button:active {
} }
#sys p { #sys p {
height: 166px; height: 206px;
} }
#sys { #sys {
......
html{height:100%;overflow:hidden}html,body{margin:0;padding:0}body{background-color:#f3f1e5;color:#333;font-family:\5fae\8f6f\96c5\9ed1;font-size:small;height:100%}h2{background-color:#ececec;background-image:linear-gradient(#f9f9f9,#ececec);background-repeat:repeat-x;border-radius:4px 4px 0 0;font-size:16px;margin:0;padding:10px 20px;text-shadow:0 -1px 0 rgba(255,255,255,0.5)}input{border:1px solid #ccc;border-radius:3px 3px 3px 3px;box-shadow:0 1px 2px rgba(0,0,0,0.075) inset;font-size:13px;margin:15px 0;padding:7px 8px;transition:all .15s ease-in 0s;vertical-align:middle;width:410px;font-family:\5fae\8f6f\96c5\9ed1;font-size:small}input:focus{box-shadow:0 1px 2px rgba(0,0,0,0.075) inset,0 0 5px rgbargba(200,200,200,0.9);border:1px solid #e6e5d9}.form{padding:20px}label{font-size:13px}button{position:relative;display:inline-block;font-size:13px;font-weight:700;color:#333;text-shadow:0 1px 0 rgba(255,255,255,0.9);white-space:nowrap;background-color:#eaeaea;background-image:linear-gradient(#fafafa,#eaeaea);background-repeat:repeat-x;border-radius:3px;border:1px solid #ddd;border-bottom-color:#c5c5c5;box-shadow:0 1px 3px rgba(0,0,0,0.075);vertical-align:baseline;cursor:pointer;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-appearance:none;outline:0;padding:7px 15px;margin-top:10px}button:hover,button:active{color:#fff;text-decoration:none;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#3072b3;background-image:linear-gradient(#599bcd,#3072b3);background-repeat:repeat-x}.clear{background-color:transparent;border:0;clear:both;display:block;font-size:0;height:0;line-height:0;overflow:hidden}.none{display:none}.main .icon{position:absolute;right:0;top:0;width:16px;height:16px}.solo{color:orangered;font-weight:bold}.logo{float:left;padding:162px 12px 0;width:153px}.wrapper{height:auto;min-height:100%;position:relative}.wrap{border-top:5px solid #e6e5d9;min-height:400px}.content{background:url("../images/zz.jpg") repeat-x scroll center bottom white;border-color:#e6e5d9;border-style:solid solid none;border-width:1px;margin:0 auto;position:relative;width:700px;top:60px}.main{border-left:1px solid #e6e5d9;float:right;font-size:15px;margin:24px 0;padding:12px 24px;width:470px;height:338px}.main a{text-decoration:none}.main li{margin:6px 0 6px 16px}.footerWrapper{background-color:#fff;border-top:1px solid #e6e5d9;bottom:0;padding:12px 0;position:absolute;text-align:center;width:100%}.footerWrapper a{text-decoration:none}.article-pwd>div,.article-pwd>form{margin:0 20px}.article-pwd>div{margin-bottom:10px;max-height:264px;overflow:auto;word-wrap:break-word}.img-403,.img-500{box-shadow:0 0 5px #e6e5d9;margin:20px 0 0 45px;padding:5px}.a-403,.a-500{margin:20px 50px 0 0;text-align:right}.a-403{margin:10px 75px 0 0}.img-500{margin:20px 0 0 25px}.a-500{margin:25px 35px 0 0}.kill img{position:absolute;right:40px;top:200px}.kill ul{margin-bottom:50px}.kill p{margin:12px 20px}.kill span{margin-left:20px}#init{position:absolute;top:81px;width:470px}#init input,.register input{margin:5px 0;padding:5px 8px}.register{height:400px}#sys p{height:166px}#sys{padding:0 20px}#initButton{margin-right:10px}#tip{color:#21759b;font-weight:bold;margin-left:10px} html{height:100%;overflow:hidden}html,body{margin:0;padding:0}body{background-color:#f3f1e5;color:#333;font-family:\5fae\8f6f\96c5\9ed1;font-size:small;height:100%}h2{background-color:#ececec;background-image:linear-gradient(#f9f9f9,#ececec);background-repeat:repeat-x;border-radius:4px 4px 0 0;font-size:16px;margin:0;padding:10px 20px;text-shadow:0 -1px 0 rgba(255,255,255,0.5)}input{border:1px solid #ccc;border-radius:3px 3px 3px 3px;box-shadow:0 1px 2px rgba(0,0,0,0.075) inset;font-size:13px;margin:15px 0;padding:7px 8px;transition:all .15s ease-in 0s;vertical-align:middle;width:410px;font-family:\5fae\8f6f\96c5\9ed1;font-size:small}input:focus{box-shadow:0 1px 2px rgba(0,0,0,0.075) inset,0 0 5px rgbargba(200,200,200,0.9);border:1px solid #e6e5d9}.form{padding:20px}label{font-size:13px}button{position:relative;display:inline-block;font-size:13px;font-weight:700;color:#333;text-shadow:0 1px 0 rgba(255,255,255,0.9);white-space:nowrap;background-color:#eaeaea;background-image:linear-gradient(#fafafa,#eaeaea);background-repeat:repeat-x;border-radius:3px;border:1px solid #ddd;border-bottom-color:#c5c5c5;box-shadow:0 1px 3px rgba(0,0,0,0.075);vertical-align:baseline;cursor:pointer;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-appearance:none;outline:0;padding:7px 15px;margin-top:10px}button:hover,button:active{color:#fff;text-decoration:none;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#3072b3;background-image:linear-gradient(#599bcd,#3072b3);background-repeat:repeat-x}.clear{background-color:transparent;border:0;clear:both;display:block;font-size:0;height:0;line-height:0;overflow:hidden}.none{display:none}.main .icon{position:absolute;right:0;top:0;width:16px;height:16px}.solo{color:orangered;font-weight:bold}.logo{float:left;padding:162px 12px 0;width:153px}.wrapper{height:auto;min-height:100%;position:relative}.wrap{border-top:5px solid #e6e5d9;min-height:400px}.content{background:url("../images/zz.jpg") repeat-x scroll center bottom white;border-color:#e6e5d9;border-style:solid solid none;border-width:1px;margin:0 auto;position:relative;width:700px;top:60px}.main{border-left:1px solid #e6e5d9;float:right;font-size:15px;margin:24px 0;padding:12px 24px;width:470px;height:338px}.main a{text-decoration:none}.main li{margin:6px 0 6px 16px}.footerWrapper{background-color:#fff;border-top:1px solid #e6e5d9;bottom:0;padding:12px 0;position:absolute;text-align:center;width:100%}.footerWrapper a{text-decoration:none}.article-pwd>div,.article-pwd>form{margin:0 20px}.article-pwd>div{margin-bottom:10px;max-height:264px;overflow:auto;word-wrap:break-word}.img-403,.img-500{box-shadow:0 0 5px #e6e5d9;margin:20px 0 0 45px;padding:5px}.a-403,.a-500{margin:20px 50px 0 0;text-align:right}.a-403{margin:10px 75px 0 0}.img-500{margin:20px 0 0 25px}.a-500{margin:25px 35px 0 0}.kill img{position:absolute;right:40px;top:200px}.kill ul{margin-bottom:50px}.kill p{margin:12px 20px}.kill span{margin-left:20px}#init{position:absolute;top:81px;width:470px}#init .form{padding:10px 20px}#init input,.register input{margin:5px 0;padding:5px 8px}.register{height:400px}#sys p{height:206px}#sys{padding:0 20px}#initButton{margin-right:10px}#tip{color:#21759b;font-weight:bold;margin-left:10px}
\ No newline at end of file \ No newline at end of file
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
html { html {
height: 100%; height: 100%;
overflow: hidden;
} }
body { body {
...@@ -30,6 +31,7 @@ ...@@ -30,6 +31,7 @@
font-family: \5fae\8f6f\96c5\9ed1; font-family: \5fae\8f6f\96c5\9ed1;
font-size: small; font-size: small;
height: 100%; height: 100%;
overflow: hidden;
} }
.wrapper { .wrapper {
...@@ -106,6 +108,7 @@ ...@@ -106,6 +108,7 @@
${initIntroLabel} ${initIntroLabel}
<button onclick='initSys();' id="initButton">${initLabel}</button> <button onclick='initSys();' id="initButton">${initLabel}</button>
<button onclick='returnTo();'>${previousStepLabel}</button> <button onclick='returnTo();'>${previousStepLabel}</button>
<span id="tipInit"></span>
<span class="clear"></span> <span class="clear"></span>
</div> </div>
</div> </div>
...@@ -154,7 +157,7 @@ ...@@ -154,7 +157,7 @@
var getUserInfo = function() { var getUserInfo = function() {
if (validate()) { if (validate()) {
$("#init").animate({ $("#init").animate({
"top": -190 "top": -178
}); });
$("#user").animate({ $("#user").animate({
...@@ -165,7 +168,7 @@ ...@@ -165,7 +168,7 @@
"display": "block", "display": "block",
"opacity": 1 "opacity": 1
}); });
$(window).unbind().keydown(function(e) { $(window).unbind().keydown(function(e) {
if (e.keyCode === 27) {// esc if (e.keyCode === 27) {// esc
returnTo(); returnTo();
...@@ -202,15 +205,15 @@ ...@@ -202,15 +205,15 @@
if (confirm("${confirmInitLabel}")) { if (confirm("${confirmInitLabel}")) {
$(window).unbind(); $(window).unbind();
$("#tip").html("<img src='${staticServePath}/images/loading.gif'/> loading...") $("#tipInit").html("<img src='${staticServePath}/images/loading.gif'/> loading...");
$.ajax({ $.ajax({
url: "${contextPath}/init", url: "${contextPath}/init",
type: "POST", type: "POST",
data: JSON.stringify(requestJSONObject), data: JSON.stringify(requestJSONObject),
success: function(result, textStatus) { success: function(result, textStatus) {
if (!result.sc) { if (!result.sc) {
$("#tip").text(result.msg); $("#tipInit").text(result.msg);
;
return; return;
} }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* *
* @author <a href="mailto:LLY219@gmail.com">Liyuan Li</a> * @author <a href="mailto:LLY219@gmail.com">Liyuan Li</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.3.3, Jun 4, 2013 * @version 1.0.3.3, Sep 30, 2013
*/ */
admin.article = { admin.article = {
// 当发文章,取消发布,更新文章时设置为 false。不需在离开编辑器时进行提示。 // 当发文章,取消发布,更新文章时设置为 false。不需在离开编辑器时进行提示。
...@@ -456,11 +456,7 @@ admin.article = { ...@@ -456,11 +456,7 @@ admin.article = {
return; return;
} }
if (admin.article.status.id) { if (admin.article.status.id) {
if (admin.article.status.isArticle) { if (!admin.article.status.isArticle) {
admin.article.status.isArticle = false;
admin.article.setStatus();
admin.article.unPublish(true);
} else {
admin.article.update(false, true); admin.article.update(false, true);
} }
} else { } else {
......
...@@ -875,7 +875,7 @@ $.extend(TablePaginate.prototype, { ...@@ -875,7 +875,7 @@ $.extend(TablePaginate.prototype, {
* *
* @author <a href="mailto:LLY219@gmail.com">Liyuan Li</a> * @author <a href="mailto:LLY219@gmail.com">Liyuan Li</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.3.3, Jun 4, 2013 * @version 1.0.3.3, Sep 30, 2013
*/ */
admin.article = { admin.article = {
// 当发文章,取消发布,更新文章时设置为 false。不需在离开编辑器时进行提示。 // 当发文章,取消发布,更新文章时设置为 false。不需在离开编辑器时进行提示。
...@@ -1313,11 +1313,7 @@ admin.article = { ...@@ -1313,11 +1313,7 @@ admin.article = {
return; return;
} }
if (admin.article.status.id) { if (admin.article.status.id) {
if (admin.article.status.isArticle) { if (!admin.article.status.isArticle) {
admin.article.status.isArticle = false;
admin.article.setStatus();
admin.article.unPublish(true);
} else {
admin.article.update(false, true); admin.article.update(false, true);
} }
} else { } else {
...@@ -3542,7 +3538,7 @@ admin.userList = { ...@@ -3542,7 +3538,7 @@ admin.userList = {
} else if (!/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test($("#userEmail" + status).val())) { } else if (!/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test($("#userEmail" + status).val())) {
$("#tipMsg").text(Label.mailInvalidLabel); $("#tipMsg").text(Label.mailInvalidLabel);
$("#userEmail" + status).focus(); $("#userEmail" + status).focus();
} else if ($("#userPassword" + status).val().replace(/\s/g, "") === "") { } else if ($("#userPassword" + status).val() === "") {
$("#tipMsg").text(Label.passwordEmptyLabel); $("#tipMsg").text(Label.passwordEmptyLabel);
$("#userPassword" + status).focus(); $("#userPassword" + status).focus();
} else { } else {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -338,7 +338,7 @@ admin.userList = { ...@@ -338,7 +338,7 @@ admin.userList = {
} else if (!/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test($("#userEmail" + status).val())) { } else if (!/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test($("#userEmail" + status).val())) {
$("#tipMsg").text(Label.mailInvalidLabel); $("#tipMsg").text(Label.mailInvalidLabel);
$("#userEmail" + status).focus(); $("#userEmail" + status).focus();
} else if ($("#userPassword" + status).val().replace(/\s/g, "") === "") { } else if ($("#userPassword" + status).val() === "") {
$("#tipMsg").text(Label.passwordEmptyLabel); $("#tipMsg").text(Label.passwordEmptyLabel);
$("#userPassword" + status).focus(); $("#userPassword" + status).focus();
} else { } else {
......
...@@ -155,28 +155,6 @@ var Util = { ...@@ -155,28 +155,6 @@ var Util = {
Util.killIE(); Util.killIE();
Util.setTopBar(); Util.setTopBar();
}, },
/**
* @description topbar 清除缓存按钮事件
*/
clearCache: function(all) {
var data = '';
if (all === "all") {
data = '{"all": "all", "URI": ""}';
} else {
data = '{"all": "all", "URI": "' + window.location.pathname + '"}';
}
$.ajax({
type: "POST",
url: latkeConfig.servePath + "/clear-cache.do",
cache: false,
contentType: "application/json",
data: data,
success: function(result) {
window.location.reload();
}
});
},
/** /**
* @description 替换侧边栏表情为图片 * @description 替换侧边栏表情为图片
* @param {Dom} comments 评论内容元素 * @param {Dom} comments 评论内容元素
......
...@@ -13,4 +13,4 @@ ...@@ -13,4 +13,4 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
var Util={error:function(){$("#tipMsg").text("Error: "+arguments[0]+" File: "+arguments[1]+"\nLine: "+arguments[2]+" please report this issue on https://github.com/b3log/b3log-solo/issues/new");$("#loadMsg").text("")},killIE:function(){var addKillPanel=function(){if(Cookie.readCookie("showKill")===""){var left=($(window).width()-701)/2,top=($(window).height()-420)/2;$("body").append("<div style='display: block; height: 100%; width: 100%; position: fixed; background-color: rgb(0, 0, 0); opacity: 0.6; top: 0px;z-index:11'></div><iframe style='left:"+left+"px;z-index:20;top: "+top+"px; position: fixed; border: 0px none; width: 701px; height: 420px;' src='"+latkeConfig.servePath+"/kill-browser.html'></iframe>")}};if($.browser.msie){if($.browser.version==="6.0"||$.browser.version==="7.0"){addKillPanel();return}if(window.external&&window.external.twGetRunPath){var path=external.twGetRunPath();if(path&&path.toLowerCase().indexOf("360se")>-1&&window.location.href.indexOf("admin-index")>-1){addKillPanel();return}}}},replaceEmString:function(str){var commentSplited=str.split("[em");if(commentSplited.length===1){return str}str=commentSplited[0];for(var j=1;j<commentSplited.length;j++){var key=commentSplited[j].substr(0,2);str+="<img src='"+latkeConfig.staticServePath+"/skins/"+Label.skinDirName+"/images/emotions/em"+key+".png' alt='"+Label["em"+key+"Label"]+"' title='"+Label["em"+key+"Label"]+"'/>"+commentSplited[j].substr(3)}return str},proessURL:function(url){if(!/^\w+:\/\//.test(url)){url="http://"+url}return url},switchMobile:function(skin){Cookie.createCookie("btouch_switch_toggle",skin,365);setTimeout(function(){location.reload()},1250)},setTopBar:function(){var $top=$("#top");if($top.length===1){var $showTop=$("#showTop");$showTop.click(function(){$top.slideDown();$showTop.hide()});$("#hideTop").click(function(){$top.slideUp();$showTop.show()})}},goTop:function(){var acceleration=acceleration||0.1;var y=$(window).scrollTop();var speed=1+acceleration;window.scrollTo(0,Math.floor(y/speed));if(y>0){var invokeFunction="Util.goTop("+acceleration+")";window.setTimeout(invokeFunction,16)}},goBottom:function(bottom){if(!bottom){bottom=0}window.scrollTo(0,$("body").height()-$(window).height()-bottom)},init:function(){Util.killIE();Util.setTopBar()},clearCache:function(all){var data="";if(all==="all"){data='{"all": "all", "URI": ""}'}else{data='{"all": "all", "URI": "'+window.location.pathname+'"}'}$.ajax({type:"POST",url:latkeConfig.servePath+"/clear-cache.do",cache:false,contentType:"application/json",data:data,success:function(result){window.location.reload()}})},replaceSideEm:function(comments){for(var i=0;i<comments.length;i++){var $comment=$(comments[i]);$comment.html(Util.replaceEmString($comment.html()))}},buildTags:function(id){id=id||"tags";var classes=["tags1","tags2","tags3","tags4","tags5"],bList=$("#"+id+" b").get();var max=parseInt($("#"+id+" b").last().text());var distance=Math.ceil(max/classes.length);for(var i=0;i<bList.length;i++){var num=parseInt(bList[i].innerHTML);for(var j=0;j<classes.length;j++){if(num>j*distance&&num<=(j+1)*distance){bList[i].parentNode.className=classes[j];break}}}$("#"+id).html($("#"+id+" li").get().sort(function(a,b){var valA=$(a).find("span").text().toLowerCase();var valB=$(b).find("span").text().toLowerCase();return valA.localeCompare(valB)}))},toDate:function(time,format){var dateTime=new Date(time);var o={"M+":dateTime.getMonth()+1,"d+":dateTime.getDate(),"H+":dateTime.getHours(),"m+":dateTime.getMinutes(),"s+":dateTime.getSeconds(),"q+":Math.floor((dateTime.getMonth()+3)/3),S:dateTime.getMilliseconds()};if(/(y+)/.test(format)){format=format.replace(RegExp.$1,(dateTime.getFullYear()+"").substr(4-RegExp.$1.length))}for(var k in o){if(new RegExp("("+k+")").test(format)){format=format.replace(RegExp.$1,RegExp.$1.length==1?o[k]:("00"+o[k]).substr((""+o[k]).length))}}return format},getWinHeight:function(){if(window.innerHeight){return window.innerHeight}if(document.compatMode==="CSS1Compat"){return window.document.documentElement.clientHeight}return window.document.body.clientHeight}};if(!Cookie){var Cookie={readCookie:function(name){var nameEQ=name+"=";var ca=document.cookie.split(";");for(var i=0;i<ca.length;i++){var c=ca[i];while(c.charAt(0)==" "){c=c.substring(1,c.length)}if(c.indexOf(nameEQ)==0){return decodeURIComponent(c.substring(nameEQ.length,c.length))}}return""},eraseCookie:function(name){this.createCookie(name,"",-1)},createCookie:function(name,value,days){var expires="";if(days){var date=new Date();date.setTime(date.getTime()+(days*24*60*60*1000));expires="; expires="+date.toGMTString()}document.cookie=name+"="+encodeURIComponent(value)+expires+"; path=/"}}}; var Util={error:function(){$("#tipMsg").text("Error: "+arguments[0]+" File: "+arguments[1]+"\nLine: "+arguments[2]+" please report this issue on https://github.com/b3log/b3log-solo/issues/new");$("#loadMsg").text("")},killIE:function(){var addKillPanel=function(){if(Cookie.readCookie("showKill")===""){var left=($(window).width()-701)/2,top=($(window).height()-420)/2;$("body").append("<div style='display: block; height: 100%; width: 100%; position: fixed; background-color: rgb(0, 0, 0); opacity: 0.6; top: 0px;z-index:11'></div><iframe style='left:"+left+"px;z-index:20;top: "+top+"px; position: fixed; border: 0px none; width: 701px; height: 420px;' src='"+latkeConfig.servePath+"/kill-browser.html'></iframe>")}};if($.browser.msie){if($.browser.version==="6.0"||$.browser.version==="7.0"){addKillPanel();return}if(window.external&&window.external.twGetRunPath){var path=external.twGetRunPath();if(path&&path.toLowerCase().indexOf("360se")>-1&&window.location.href.indexOf("admin-index")>-1){addKillPanel();return}}}},replaceEmString:function(str){var commentSplited=str.split("[em");if(commentSplited.length===1){return str}str=commentSplited[0];for(var j=1;j<commentSplited.length;j++){var key=commentSplited[j].substr(0,2);str+="<img src='"+latkeConfig.staticServePath+"/skins/"+Label.skinDirName+"/images/emotions/em"+key+".png' alt='"+Label["em"+key+"Label"]+"' title='"+Label["em"+key+"Label"]+"'/>"+commentSplited[j].substr(3)}return str},proessURL:function(url){if(!/^\w+:\/\//.test(url)){url="http://"+url}return url},switchMobile:function(skin){Cookie.createCookie("btouch_switch_toggle",skin,365);setTimeout(function(){location.reload()},1250)},setTopBar:function(){var $top=$("#top");if($top.length===1){var $showTop=$("#showTop");$showTop.click(function(){$top.slideDown();$showTop.hide()});$("#hideTop").click(function(){$top.slideUp();$showTop.show()})}},goTop:function(){var acceleration=acceleration||0.1;var y=$(window).scrollTop();var speed=1+acceleration;window.scrollTo(0,Math.floor(y/speed));if(y>0){var invokeFunction="Util.goTop("+acceleration+")";window.setTimeout(invokeFunction,16)}},goBottom:function(bottom){if(!bottom){bottom=0}window.scrollTo(0,$("body").height()-$(window).height()-bottom)},init:function(){Util.killIE();Util.setTopBar()},replaceSideEm:function(comments){for(var i=0;i<comments.length;i++){var $comment=$(comments[i]);$comment.html(Util.replaceEmString($comment.html()))}},buildTags:function(id){id=id||"tags";var classes=["tags1","tags2","tags3","tags4","tags5"],bList=$("#"+id+" b").get();var max=parseInt($("#"+id+" b").last().text());var distance=Math.ceil(max/classes.length);for(var i=0;i<bList.length;i++){var num=parseInt(bList[i].innerHTML);for(var j=0;j<classes.length;j++){if(num>j*distance&&num<=(j+1)*distance){bList[i].parentNode.className=classes[j];break}}}$("#"+id).html($("#"+id+" li").get().sort(function(a,b){var valA=$(a).find("span").text().toLowerCase();var valB=$(b).find("span").text().toLowerCase();return valA.localeCompare(valB)}))},toDate:function(time,format){var dateTime=new Date(time);var o={"M+":dateTime.getMonth()+1,"d+":dateTime.getDate(),"H+":dateTime.getHours(),"m+":dateTime.getMinutes(),"s+":dateTime.getSeconds(),"q+":Math.floor((dateTime.getMonth()+3)/3),S:dateTime.getMilliseconds()};if(/(y+)/.test(format)){format=format.replace(RegExp.$1,(dateTime.getFullYear()+"").substr(4-RegExp.$1.length))}for(var k in o){if(new RegExp("("+k+")").test(format)){format=format.replace(RegExp.$1,RegExp.$1.length==1?o[k]:("00"+o[k]).substr((""+o[k]).length))}}return format},getWinHeight:function(){if(window.innerHeight){return window.innerHeight}if(document.compatMode==="CSS1Compat"){return window.document.documentElement.clientHeight}return window.document.body.clientHeight}};if(!Cookie){var Cookie={readCookie:function(name){var nameEQ=name+"=";var ca=document.cookie.split(";");for(var i=0;i<ca.length;i++){var c=ca[i];while(c.charAt(0)==" "){c=c.substring(1,c.length)}if(c.indexOf(nameEQ)==0){return decodeURIComponent(c.substring(nameEQ.length,c.length))}}return""},eraseCookie:function(name){this.createCookie(name,"",-1)},createCookie:function(name,value,days){var expires="";if(days){var date=new Date();date.setTime(date.getTime()+(days*24*60*60*1000));expires="; expires="+date.toGMTString()}document.cookie=name+"="+encodeURIComponent(value)+expires+"; path=/"}}};
\ No newline at end of file \ No newline at end of file
This diff is collapsed.
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>${blogTitle}</title> <title>${blogTitle}</title>
<meta name="keywords" content="GAE 博客,blog,b3log,kill IE6" /> <meta name="keywords" content="Java 博客,blog,b3log,kill IE6" />
<meta name="description" content="An open source blog based on GAE Java,GAE Java 开源博客,Let's kill IE6" /> <meta name="description" content="An open source blog based on GAE Java,GAE Java 开源博客,Let's kill IE6" />
<meta name="owner" content="B3log Team" /> <meta name="owner" content="B3log Team" />
<meta name="author" content="B3log Team" /> <meta name="author" content="B3log Team" />
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>${welcomeToSoloLabel} B3log Solo!</title> <title>${welcomeToSoloLabel} B3log Solo!</title>
<meta name="keywords" content="GAE 博客,GAE blog,b3log" /> <meta name="keywords" content="Java 博客,GAE blog,b3log" />
<meta name="description" content="An open source blog based on GAE Java,GAE Java 开源博客" /> <meta name="description" content="An open source blog based on GAE Java,GAE Java 开源博客" />
<meta name="owner" content="B3log Team" /> <meta name="owner" content="B3log Team" />
<meta name="author" content="B3log Team" /> <meta name="author" content="B3log Team" />
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
return; return;
} }
if ($("#userPassword").val().replace(/\s/g, "") === "") { if ($("#userPassword").val() === "") {
$("#tip").text("${passwordEmptyLabel}"); $("#tip").text("${passwordEmptyLabel}");
$("#userPassword").focus(); $("#userPassword").focus();
return; return;
......
#
# Copyright (c) 2009, 2010, 2011, B3log Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# Description: Language configurations(en_US) of plugin admin-cache.
# Version: 1.0.0.3, Jun 25, 2011
# Author: Liyuan Li
# Author: Liang Ding
#
cacheMgmtLabel=Cache
typeLabel=Type
hitCountLabel=Hit Count
pageCacheStatus1Label=Page Cache Status:
pageCachedCnt1Label=Cached Page Count:
cachedCount1Label=Cached Count:
hitCount1Label=Hit Count:
cachedBytes1Label=Cached Bytes:
hitBytes1Label=Hit Bytes:
missCount1Label=Miss Count:
\ No newline at end of file
#
# Copyright (c) 2009, 2010, 2011, B3log Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# Description: Language configurations(zh_CN) of plugin admin-cache.
# Version: 1.0.0.4, Jun 26, 2011
# Author: Liyuan Li
# Author: Liang Ding
#
cacheMgmtLabel=\u7f13\u5b58\u7ba1\u7406
typeLabel=\u7c7b\u578b
hitCountLabel=\u547d\u4e2d\u6b21\u6570
pageCacheStatus1Label=\u9875\u9762\u7f13\u5b58\u72b6\u6001\uff1a
pageCachedCnt1Label=\u5df2\u7f13\u5b58\u9875\u9762\u6570\uff1a
cachedCount1Label=\u5f53\u524d\u7f13\u5b58\u6570\uff1a
hitCount1Label=\u547d\u4e2d\u6b21\u6570\uff1a
cachedBytes1Label=\u5df2\u7f13\u5b58\u5b57\u8282\uff1a
hitBytes1Label=\u5df2\u547d\u4e2d\u5b57\u8282\uff1a
missCount1Label=\u4e22\u5931\u6b21\u6570\uff1a
\ No newline at end of file
<style type="text/css">
#cacheContent {
line-height: 28px;
padding: 12px;
}
</style>
<div id="cachePlugin">
<div id="cacheContent"></div>
<div id="cacheTable"></div>
<div id="cachePagination" class="margin12 right"></div>
<div class="clear"></div>
</div>
<script type="text/javascript">
plugins["cache-list"] = {
tablePagination: new TablePaginate("cache"),
getList: function (pageNum) {
var that = this;
$("#loadMsg").text("${loadingLabel}");
$.ajax({
url: latkeConfig.servePath + "/console/plugins/admin-cache/pages/" + pageNum + "/" + Label.PAGE_SIZE + "/" + Label.WINDOW_SIZE,
type: "GET",
cache: false,
success: function(result, textStatus){
if (!result.sc) {
$("#tipMsg").text(result.msg);
return;
}
var caches = result.pages;
var cacheData = caches;
for (var i = 0; i < caches.length; i++) {
cacheData[i].cachedTitle = "<a href='" + caches[i].cachedLink + "' target='_blank'>"
+ caches[i].cachedTitle + "</a>";
cacheData[i].cachedTime = $.bowknot.getDate(cacheData[i].cachedTime, 1);
}
that.tablePagination.updateTablePagination(cacheData, pageNum, result.pagination);
$("#loadMsg").text("");
}
});
},
changeStatus: function (it) {
$("#loadMsg").text("${loadingLabel}");
var $it = $(it);
var flag = "true";
if ($it.text() === "${enabledLabel}") {
flag = "false";
}
$.ajax({
url: latkeConfig.servePath + "/console/plugins/admin-cache/enable/" + flag,
type: "PUT",
cache: false,
success: function(result, textStatus){
if (!result.sc) {
$("#tipMsg").text(result.msg);
return;
}
if ($it.text() === "${enabledLabel}") {
$it.text("${disabledLabel}");
} else {
$it.text("${enabledLabel}");
}
$("#tipMsg").text("${updateSuccLabel}");
$("#loadMsg").text("");
}
});
},
getCache: function () {
$("#loadMsg").text("${loadingLabel}");
$.ajax({
url: latkeConfig.servePath + "/console/plugins/admin-cache/status/",
type: "GET",
cache: false,
success: function(result, textStatus){
if (!result.sc) {
$("#tipMsg").text(result.msg);
return;
}
var pageCacheStatusLabel = "${disabledLabel}";
if (result.pageCacheEnabled) {
pageCacheStatusLabel = "${enabledLabel}";
}
var cacheHTML = "${pageCacheStatus1Label}&nbsp;<button onclick=\"window.plugins['cache-list'].changeStatus(this);\">"
+ pageCacheStatusLabel
+ "</button>&nbsp;&nbsp;${pageCachedCnt1Label}<span class='f-blue'>" + result.pageCachedCnt;
$("#cacheContent").html(cacheHTML);
$("#loadMsg").text("");
}
});
},
init: function (page) {
this.tablePagination.buildTable([{
style: "padding-left: 6px;",
text: "${typeLabel}",
index: "cachedType",
width: 220
}, {
style: "padding-left: 6px;",
text: "${titleLabel}",
index: "cachedTitle",
minWidth: 300
}, {
style: "padding-left: 6px;",
text: "${hitCountLabel}",
index: "cachedHitCount",
width: 120
}, {
style: "padding-left: 6px;",
text: "${sizeLabel}(Byte)",
index: "cachedBtypesLength",
width: 120
}, {
style: "padding-left: 6px;",
text: "${createDateLabel}",
index: "cachedTime",
width: 160
}]);
this.tablePagination.initPagination();
this.getList(page);
this.getCache();
},
refresh: function (page) {
this.getList(page);
this.getCache();
}
};
/*
* 添加插件
*/
admin.plugin.add({
"id": "cache-list",
"text": "${cacheMgmtLabel}",
"path": "/tools",
"index": 6,
"content": $("#cachePlugin").html()
});
// 移除现有内容
$("#cachePlugin").remove();
</script>
\ No newline at end of file
#
# Copyright (c) 2009, 2010, 2011, B3log Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# Description: Description of plugin admin-cache.
# Version: 1.0.1.0, May 16, 2012
# Author: Liang Ding
#
rendererId=admin-index.ftl
author=<a href="http://88250.b3log.org">88250</a> & <a href="http://vanessa.b3log.org">Vanessa</a>
name=Admin Cache
version=0.1.2
types=ADMIN
classesDirPath=/WEB-INF/classes/
# TODO: libDirPath=/WEB-INF/lib/
pluginClass=
eventListenerClasses=
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>${blogTitle}</title> <title>${blogTitle}</title>
<meta name="keywords" content="GAE 博客,blog,b3log,kill IE6" /> <meta name="keywords" content="Java 博客,blog,b3log,kill IE6" />
<meta name="description" content="An open source blog based on GAE Java,GAE Java 开源博客,用户注册" /> <meta name="description" content="An open source blog based on GAE Java,GAE Java 开源博客,用户注册" />
<meta name="owner" content="B3log Team" /> <meta name="owner" content="B3log Team" />
<meta name="author" content="B3log Team" /> <meta name="author" content="B3log Team" />
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
} else if (2 > userName.length || userName.length > 20) { } else if (2 > userName.length || userName.length > 20) {
$("#tip").text("${nameTooLongLabel}"); $("#tip").text("${nameTooLongLabel}");
$("#userName").focus(); $("#userName").focus();
} else if ($("#userPassword").val().replace(/\s/g, "") === "") { } else if ($("#userPassword").val() === "") {
$("#tip").text("${passwordEmptyLabel}"); $("#tip").text("${passwordEmptyLabel}");
$("#userPassword").focus(); $("#userPassword").focus();
} else if ($("#userPassword").val() !== $("#userPasswordConfirm").val()) { } else if ($("#userPassword").val() !== $("#userPasswordConfirm").val()) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment