Commit 2caafaa9 authored by Liang Ding's avatar Liang Ding

Fixed #161

parent 21772b2f
......@@ -7,4 +7,12 @@
<goal>cobertura:cobertura</goal>
</goals>
</action>
<action>
<actionName>CUSTOM-jacobe-jacobe</actionName>
<displayName>jacobe-jacobe</displayName>
<goals>
<goal>jacobe:jacobe</goal>
</goals>
</action>
</actions>
......@@ -96,6 +96,36 @@
</resources>
<plugins>
<plugin>
<groupId>com.tiobe.jacobe</groupId>
<artifactId>maven-jacobe-plugin</artifactId>
<version>1.0</version>
<configuration>
<jacobeExecutable>${jacobeExecutable}</jacobeExecutable>
<rules>
<param>indent=4</param>
<param>continuationindent=2</param>
</rules>
<configurationFile>../src/main/resources/etc/jacobe/sun.cfg</configurationFile>
<comparisonThreshold>0.01</comparisonThreshold>
<javadoc>private</javadoc>
<noAssert>true</noAssert>
<noEnum>false</noEnum>
<noBackup>true</noBackup>
<overwrite>true</overwrite>
<outputExtension>formatted</outputExtension>
<input>${basedir}/src/main/java</input>
</configuration>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>jacobe</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
......@@ -160,5 +190,34 @@
</plugins>
</build>
<profiles>
<profile>
<id>linux</id>
<activation>
<os>
<family>linux</family>
</os>
</activation>
<properties>
<jacobeExecutable>
../src/main/resources/etc/jacobe/linux/jacobe.exe
</jacobeExecutable>
</properties>
</profile>
<profile>
<id>windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<properties>
<jacobeExecutable>
../src/main/resources/etc/jacobe/win32/jacobe.exe
</jacobeExecutable>
</properties>
</profile>
</profiles>
</project>
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContextEvent;
......@@ -49,6 +50,7 @@ import org.b3log.solo.util.Skins;
import org.b3log.solo.util.Statistics;
import org.json.JSONObject;
/**
* B3log Solo servlet listener.
*
......@@ -62,14 +64,17 @@ public final class SoloServletListener extends AbstractServletListener {
* B3log Solo version.
*/
public static final String VERSION = "0.5.5";
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(SoloServletListener.class.getName());
/**
* JSONO print indent factor.
*/
public static final int JSON_PRINT_INDENT_FACTOR = 4;
/**
* Enter escape.
*/
......@@ -109,7 +114,7 @@ public final class SoloServletListener extends AbstractServletListener {
LOGGER.info("Initialized the context");
Stopwatchs.end();
LOGGER.log(Level.FINE, "Stopwatch: {0}{1}", new Object[]{Strings.LINE_SEPARATOR, Stopwatchs.getTimingStat()});
LOGGER.log(Level.FINE, "Stopwatch: {0}{1}", new Object[] {Strings.LINE_SEPARATOR, Stopwatchs.getTimingStat()});
}
@Override
......@@ -120,18 +125,17 @@ public final class SoloServletListener extends AbstractServletListener {
}
@Override
public void sessionCreated(final HttpSessionEvent httpSessionEvent) {
}
public void sessionCreated(final HttpSessionEvent httpSessionEvent) {}
// Note: This method will never invoked on GAE production environment
@Override
public void sessionDestroyed(final HttpSessionEvent httpSessionEvent) {
}
public void sessionDestroyed(final HttpSessionEvent httpSessionEvent) {}
@Override
public void requestInitialized(final ServletRequestEvent servletRequestEvent) {
final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequestEvent.getServletRequest();
final String requestURI = httpServletRequest.getRequestURI();
Stopwatchs.start("Request Initialized[requestURI=" + requestURI + "]");
if (Requests.searchEngineBotRequest(httpServletRequest)) {
......@@ -140,9 +144,9 @@ public final class SoloServletListener extends AbstractServletListener {
} else {
// Gets the session of this request
final HttpSession session = httpServletRequest.getSession();
LOGGER.log(Level.FINE, "Gets a session[id={0}, remoteAddr={1}, User-Agent={2}, isNew={3}]",
new Object[]{session.getId(), httpServletRequest.getRemoteAddr(), httpServletRequest.getHeader("User-Agent"),
session.isNew()});
LOGGER.log(Level.FINE, "Gets a session[id={0}, remoteAddr={1}, User-Agent={2}, isNew={3}]", new Object[] {
session.getId(), httpServletRequest.getRemoteAddr(), httpServletRequest.getHeader("User-Agent"), session.isNew()});
// Online visitor count
Statistics.onlineVisitorCount(httpServletRequest);
}
......@@ -154,7 +158,7 @@ public final class SoloServletListener extends AbstractServletListener {
public void requestDestroyed(final ServletRequestEvent servletRequestEvent) {
Stopwatchs.end();
LOGGER.log(Level.FINE, "Stopwatch: {0}{1}", new Object[]{Strings.LINE_SEPARATOR, Stopwatchs.getTimingStat()});
LOGGER.log(Level.FINE, "Stopwatch: {0}{1}", new Object[] {Strings.LINE_SEPARATOR, Stopwatchs.getTimingStat()});
Stopwatchs.release();
super.requestDestroyed(servletRequestEvent);
......@@ -193,6 +197,7 @@ public final class SoloServletListener extends AbstractServletListener {
Skins.loadSkins(preference);
final boolean pageCacheEnabled = preference.getBoolean(Preference.PAGE_CACHE_ENABLED);
Templates.enableCache(pageCacheEnabled);
} catch (final Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
......@@ -258,6 +263,7 @@ public final class SoloServletListener extends AbstractServletListener {
try {
final PreferenceRepository preferenceRepository = PreferenceRepositoryImpl.getInstance();
final JSONObject preference = preferenceRepository.get(Preference.PREFERENCE);
if (null == preference) { // Did not initialize yet
return;
}
......@@ -266,8 +272,7 @@ public final class SoloServletListener extends AbstractServletListener {
String desiredView = Requests.mobileSwitchToggle(httpServletRequest);
if (desiredView == null && !Requests.mobileRequest(httpServletRequest)
|| desiredView != null && desiredView.equals("normal")) {
if (desiredView == null && !Requests.mobileRequest(httpServletRequest) || desiredView != null && desiredView.equals("normal")) {
desiredView = preference.getString(Skin.SKIN_DIR_NAME);
} else {
desiredView = "mobile";
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.api.symphony;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
......@@ -38,6 +39,7 @@ import org.b3log.solo.util.QueryResults;
import org.json.JSONObject;
import org.jsoup.Jsoup;
/**
* Article receiver (from B3log Symphony).
*
......@@ -52,14 +54,17 @@ public final class ArticleReceiver {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(ArticleReceiver.class.getName());
/**
* Preference query service.
*/
private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance();
/**
* Article management service.
*/
private ArticleMgmtService articleMgmtService = ArticleMgmtService.getInstance();
/**
* Article abstract length.
*/
......@@ -100,6 +105,7 @@ public final class ArticleReceiver {
public void addArticle(final HttpServletRequest request, final HttpServletResponse response, final HTTPRequestContext context)
throws Exception {
final JSONRenderer renderer = new JSONRenderer();
context.setRenderer(renderer);
final JSONObject ret = new JSONObject();
......@@ -122,6 +128,7 @@ public final class ArticleReceiver {
article.put(Article.ARTICLE_AUTHOR_EMAIL, admin.getString(User.USER_EMAIL));
final String plainTextContent = Jsoup.parse(article.optString(Article.ARTICLE_CONTENT)).text();
if (plainTextContent.length() > ARTICLE_ABSTRACT_LENGTH) {
article.put(Article.ARTICLE_ABSTRACT, plainTextContent.substring(0, ARTICLE_ABSTRACT_LENGTH) + "....");
} else {
......@@ -133,8 +140,9 @@ public final class ArticleReceiver {
article.put(Article.ARTICLE_VIEW_PWD, "");
String content = article.getString(Article.ARTICLE_CONTENT);
final String articleId = article.getString(Keys.OBJECT_ID);
content += "<br/><br/><p style='font-size: 12px;'><i>该文章同步自 <a href='http://symphony.b3log.org/article/"
+ articleId + "' target='_blank>B3log 社区</a></i></p>";
content += "<br/><br/><p style='font-size: 12px;'><i>该文章同步自 <a href='http://symphony.b3log.org/article/" + articleId
+ "' target='_blank>B3log 社区</a></i></p>";
article.put(Article.ARTICLE_CONTENT, content);
articleMgmtService.addArticle(requestJSONObject);
......@@ -148,6 +156,7 @@ public final class ArticleReceiver {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
final JSONObject jsonObject = QueryResults.defaultResult();
renderer.setJSONObject(jsonObject);
jsonObject.put(Keys.MSG, e.getMessage());
}
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.api.symphony;
import java.io.IOException;
import java.net.URL;
import java.util.Date;
......@@ -59,6 +60,7 @@ import org.b3log.solo.util.TimeZones;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Comment receiver (from B3log Symphony).
*
......@@ -73,34 +75,42 @@ public final class CommentReceiver {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(CommentReceiver.class.getName());
/**
* Comment repository.
*/
private static CommentRepository commentRepository = CommentRepositoryImpl.getInstance();
/**
* Article utilities.
*/
private static Articles articleUtils = Articles.getInstance();
/**
* Preference query service.
*/
private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance();
/**
* Article repository.
*/
private static ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance();
/**
* Statistic utilities.
*/
private static Statistics statistics = Statistics.getInstance();
/**
* Default user thumbnail.
*/
private static final String DEFAULT_USER_THUMBNAIL = "default-user-thumbnail.png";
/**
* URL fetch service.
*/
private static URLFetchService urlFetchService = URLFetchServiceFactory.getURLFetchService();
/**
* Event manager.
*/
......@@ -142,17 +152,21 @@ public final class CommentReceiver {
public void addComment(final HttpServletRequest request, final HttpServletResponse response, final HTTPRequestContext context)
throws Exception {
final JSONRenderer renderer = new JSONRenderer();
context.setRenderer(renderer);
final JSONObject ret = new JSONObject();
renderer.setJSONObject(ret);
final Transaction transaction = commentRepository.beginTransaction();
try {
final JSONObject requestJSONObject = Requests.parseRequestJSONObject(request, response);
final JSONObject symphonyCmt = requestJSONObject.optJSONObject(Comment.COMMENT);
final JSONObject preference = preferenceQueryService.getPreference();
final String keyOfSolo = preference.optString(Preference.KEY_OF_SOLO);
final String key = symphonyCmt.optString("userB3Key");
if (Strings.isEmptyOrNull(keyOfSolo) || !keyOfSolo.equals(key)) {
ret.put(Keys.STATUS_CODE, HttpServletResponse.SC_FORBIDDEN);
ret.put(Keys.MSG, "Wrong key");
......@@ -162,6 +176,7 @@ public final class CommentReceiver {
final String articleId = symphonyCmt.getString("commentOnArticleId");
final JSONObject article = articleRepository.get(articleId);
if (null == article) {
ret.put(Keys.STATUS_CODE, HttpServletResponse.SC_NOT_FOUND);
ret.put(Keys.MSG, "Not found the specified article[id=" + articleId + "]");
......@@ -174,6 +189,7 @@ public final class CommentReceiver {
final String commentURL = "http://" + symphonyCmt.optString("commentAuthorURL");
final String commentId = symphonyCmt.optString(Keys.OBJECT_ID);
String commentContent = symphonyCmt.getString(Comment.COMMENT_CONTENT);
commentContent += "<br/><br/><p style='font-size: 12px;'><i>该评论同步自 <a href='http://symphony.b3log.org/article/"
+ symphonyCmt.optString("commentSymphonyArticleId") + "#" + commentId + "' target='_blank'>B3log 社区</a></i></p>";
final String originalCommentId = symphonyCmt.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID);
......@@ -188,6 +204,7 @@ public final class CommentReceiver {
comment.put(Comment.COMMENT_CONTENT, commentContent);
final String timeZoneId = preference.getString(Preference.TIME_ZONE_ID);
final Date date = TimeZones.getTime(timeZoneId);
comment.put(Comment.COMMENT_DATE, date);
ret.put(Comment.COMMENT_DATE, Comment.DATE_FORMAT.format(date));
if (!Strings.isEmptyOrNull(originalCommentId)) {
......@@ -195,13 +212,14 @@ public final class CommentReceiver {
if (null != originalComment) {
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, originalCommentId);
final String originalCommentName = originalComment.getString(Comment.COMMENT_NAME);
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, originalCommentName);
ret.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, originalCommentName);
} else {
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, "");
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, "");
LOGGER.log(Level.WARNING, "Not found orginal comment[id={0}] of reply[name={1}, content={2}]",
new String[]{originalCommentId, commentName, commentContent});
new String[] {originalCommentId, commentName, commentContent});
}
} else {
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, "");
......@@ -215,6 +233,7 @@ public final class CommentReceiver {
comment.put(Comment.COMMENT_ON_TYPE, Article.ARTICLE);
final String commentSharpURL = getCommentSharpURLForArticle(article, commentId);
comment.put(Comment.COMMENT_SHARP_URL, commentSharpURL);
commentRepository.add(comment);
......@@ -231,6 +250,7 @@ public final class CommentReceiver {
}
// Step 5: Fire add comment event
final JSONObject eventData = new JSONObject();
eventData.put(Comment.COMMENT, comment);
eventData.put(Article.ARTICLE, article);
eventManager.fireEventSynchronously(new Event<JSONObject>(EventTypes.ADD_COMMENT_TO_ARTICLE_FROM_SYMPHONY, eventData));
......@@ -248,6 +268,7 @@ public final class CommentReceiver {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
final JSONObject jsonObject = QueryResults.defaultResult();
renderer.setJSONObject(jsonObject);
jsonObject.put(Keys.MSG, e.getMessage());
}
......@@ -285,11 +306,13 @@ public final class CommentReceiver {
// Try to set thumbnail URL using Gravatar service
final String hashedEmail = MD5.hash(commentEmail.toLowerCase());
final int size = 60;
final URL gravatarURL =
new URL("http://secure.gravatar.com/avatar/" + hashedEmail + "?s="
+ size + "&d=" + Latkes.getServePath() + "/images/default-user-thumbnail.png");
final URL gravatarURL = new URL(
"http://secure.gravatar.com/avatar/" + hashedEmail + "?s=" + size + "&d=" + Latkes.getServePath()
+ "/images/default-user-thumbnail.png");
try {
final HTTPRequest request = new HTTPRequest();
request.setURL(gravatarURL);
final HTTPResponse response = urlFetchService.fetch(request);
final int statusCode = response.getResponseCode();
......@@ -297,6 +320,7 @@ public final class CommentReceiver {
if (HttpServletResponse.SC_OK == statusCode) {
final List<HTTPHeader> headers = response.getHeaders();
boolean defaultFileLengthMatched = false;
for (final HTTPHeader httpHeader : headers) {
if ("Content-Length".equalsIgnoreCase(httpHeader.getName())) {
if (httpHeader.getValue().equals("2147")) {
......@@ -306,8 +330,8 @@ public final class CommentReceiver {
}
if (!defaultFileLengthMatched) {
thumbnailURL = "http://secure.gravatar.com/avatar/" + hashedEmail + "?s="
+ size + "&d=" + Latkes.getServePath() + "/images/default-user-thumbnail.png";
thumbnailURL = "http://secure.gravatar.com/avatar/" + hashedEmail + "?s=" + size + "&d=" + Latkes.getServePath()
+ "/images/default-user-thumbnail.png";
comment.put(Comment.COMMENT_THUMBNAIL_URL, thumbnailURL);
LOGGER.log(Level.FINEST, "Comment thumbnail[URL={0}]", thumbnailURL);
......@@ -315,7 +339,7 @@ public final class CommentReceiver {
}
} else {
LOGGER.log(Level.WARNING, "Can not fetch thumbnail from Gravatar[commentEmail={0}, statusCode={1}]",
new Object[]{commentEmail, statusCode});
new Object[] {commentEmail, statusCode});
}
} catch (final IOException e) {
LOGGER.warning(e.getMessage());
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.dev;
import java.io.IOException;
import java.util.Date;
import java.util.logging.Level;
......@@ -34,6 +35,7 @@ import org.b3log.solo.service.ArticleMgmtService;
import org.b3log.solo.service.UserQueryService;
import org.json.JSONObject;
/**
* Generates some dummy articles for development testing.
*
......@@ -47,8 +49,7 @@ public final class ArticleGenerator {
/**
* Logger.
*/
private static final Logger LOGGER =
Logger.getLogger(ArticleGenerator.class.getName());
private static final Logger LOGGER = Logger.getLogger(ArticleGenerator.class.getName());
/**
* Generates some dummy articles with the specified context.
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.event;
/**
* Event types.
*
......@@ -28,26 +29,32 @@ public final class EventTypes {
* Indicates a add article event.
*/
public static final String ADD_ARTICLE = "Add Article";
/**
* Indicates a update article event.
*/
public static final String UPDATE_ARTICLE = "Update Article";
/**
* Indicates a remove article event.
*/
public static final String REMOVE_ARTICLE = "Remove Article";
/**
* Indicates an add comment to article event.
*/
public static final String ADD_COMMENT_TO_ARTICLE = "Add Comment To Article";
/**
* Indicates an add comment (from symphony) to article event.
*/
public static final String ADD_COMMENT_TO_ARTICLE_FROM_SYMPHONY = "Add Comment To Article From Symphony";
/**
* Indicates an add comment to page event.
*/
public static final String ADD_COMMENT_TO_PAGE = "Add Comment To Page";
/**
* Indicates a remove comment event.
*/
......@@ -56,6 +63,5 @@ public final class EventTypes {
/**
* Private default constructor.
*/
private EventTypes() {
}
private EventTypes() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.event.comment;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.b3log.latke.Keys;
......@@ -35,6 +36,7 @@ import org.b3log.solo.repository.impl.CommentRepositoryImpl;
import org.b3log.solo.service.PreferenceQueryService;
import org.json.JSONObject;
/**
* This listener is responsible for processing article comment reply.
*
......@@ -48,14 +50,17 @@ public final class ArticleCommentReplyNotifier extends AbstractEventListener<JSO
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(ArticleCommentReplyNotifier.class.getName());
/**
* Comment repository.
*/
private CommentRepository commentRepository = CommentRepositoryImpl.getInstance();
/**
* Mail service.
*/
private MailService mailService = MailServiceFactory.getMailService();
/**
* Preference query service.
*/
......@@ -66,9 +71,11 @@ public final class ArticleCommentReplyNotifier extends AbstractEventListener<JSO
final JSONObject eventData = event.getData();
final JSONObject comment = eventData.optJSONObject(Comment.COMMENT);
final JSONObject article = eventData.optJSONObject(Article.ARTICLE);
LOGGER.log(Level.FINER, "Processing an event[type={0}, data={1}] in listener[className={2}]",
new Object[]{event.getType(), eventData, ArticleCommentReplyNotifier.class.getName()});
new Object[] {event.getType(), eventData, ArticleCommentReplyNotifier.class.getName()});
final String originalCommentId = comment.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID);
if (Strings.isEmptyOrNull(originalCommentId)) {
LOGGER.log(Level.FINER, "This comment[id={0}] is not a reply", comment.optString(Keys.OBJECT_ID));
return;
......@@ -78,11 +85,13 @@ public final class ArticleCommentReplyNotifier extends AbstractEventListener<JSO
final String commentEmail = comment.getString(Comment.COMMENT_EMAIL);
final JSONObject originalComment = commentRepository.get(originalCommentId);
final String originalCommentEmail = originalComment.getString(Comment.COMMENT_EMAIL);
if (originalCommentEmail.equalsIgnoreCase(commentEmail)) {
return;
}
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) {
throw new EventException("Not found preference");
}
......@@ -93,10 +102,12 @@ public final class ArticleCommentReplyNotifier extends AbstractEventListener<JSO
final String commentContent = comment.getString(Comment.COMMENT_CONTENT).replaceAll(SoloServletListener.ENTER_ESC, "<br/>");
final String commentSharpURL = comment.getString(Comment.COMMENT_SHARP_URL);
final Message message = new Message();
message.setFrom(adminEmail);
message.addRecipient(originalCommentEmail);
final JSONObject replyNotificationTemplate = preferenceQueryService.getReplyNotificationTemplate();
final String mailSubject = replyNotificationTemplate.getString("subject").replace("${blogTitle}", blogTitle);
message.setSubject(mailSubject);
final String articleTitle = article.getString(Article.ARTICLE_TITLE);
final String blogHost = preference.getString(Preference.BLOG_HOST);
......@@ -104,22 +115,19 @@ public final class ArticleCommentReplyNotifier extends AbstractEventListener<JSO
final String commentName = comment.getString(Comment.COMMENT_NAME);
final String commentURL = comment.getString(Comment.COMMENT_URL);
String commenter;
if (!"http://".equals(commentURL)) {
commenter = "<a target=\"_blank\" " + "href=\"" + commentURL + "\">" + commentName + "</a>";
} else {
commenter = commentName;
}
final String mailBody = replyNotificationTemplate.getString("body").
replace("${postLink}", articleLink).
replace("${postTitle}", articleTitle).
replace("${replier}", commenter).
replace("${replyURL}", "http://" + blogHost
+ commentSharpURL).
replace("${replyContent}", commentContent);
final String mailBody = replyNotificationTemplate.getString("body").replace("${postLink}", articleLink).replace("${postTitle}", articleTitle).replace("${replier}", commenter).replace("${replyURL}", "http://" + blogHost + commentSharpURL).replace(
"${replyContent}", commentContent);
message.setHtmlBody(mailBody);
LOGGER.log(Level.FINER, "Sending a mail[mailSubject={0}, mailBody=[{1}] to [{2}]",
new Object[]{mailSubject, mailBody, originalCommentEmail});
new Object[] {mailSubject, mailBody, originalCommentEmail});
mailService.send(message);
} catch (final Exception e) {
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.event.comment;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.b3log.latke.Keys;
......@@ -35,6 +36,7 @@ import org.b3log.solo.repository.impl.CommentRepositoryImpl;
import org.b3log.solo.service.PreferenceQueryService;
import org.json.JSONObject;
/**
* This listener is responsible for processing page comment reply.
*
......@@ -48,14 +50,17 @@ public final class PageCommentReplyNotifier extends AbstractEventListener<JSONOb
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(PageCommentReplyNotifier.class.getName());
/**
* Comment repository.
*/
private CommentRepository commentRepository = CommentRepositoryImpl.getInstance();
/**
* Mail service.
*/
private MailService mailService = MailServiceFactory.getMailService();
/**
* Preference query service.
*/
......@@ -66,9 +71,11 @@ public final class PageCommentReplyNotifier extends AbstractEventListener<JSONOb
final JSONObject eventData = event.getData();
final JSONObject comment = eventData.optJSONObject(Comment.COMMENT);
final JSONObject page = eventData.optJSONObject(Page.PAGE);
LOGGER.log(Level.FINER, "Processing an event[type={0}, data={1}] in listener[className={2}]",
new Object[]{event.getType(), eventData, PageCommentReplyNotifier.class.getName()});
new Object[] {event.getType(), eventData, PageCommentReplyNotifier.class.getName()});
final String originalCommentId = comment.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID);
if (Strings.isEmptyOrNull(originalCommentId)) {
LOGGER.log(Level.FINER, "This comment[id={0}] is not a reply", comment.optString(Keys.OBJECT_ID));
return;
......@@ -78,11 +85,13 @@ public final class PageCommentReplyNotifier extends AbstractEventListener<JSONOb
final String commentEmail = comment.getString(Comment.COMMENT_EMAIL);
final JSONObject originalComment = commentRepository.get(originalCommentId);
final String originalCommentEmail = originalComment.getString(Comment.COMMENT_EMAIL);
if (originalCommentEmail.equalsIgnoreCase(commentEmail)) {
return;
}
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) {
throw new EventException("Not found preference");
}
......@@ -90,14 +99,15 @@ public final class PageCommentReplyNotifier extends AbstractEventListener<JSONOb
final String blogTitle = preference.getString(Preference.BLOG_TITLE);
final String adminEmail = preference.getString(Preference.ADMIN_EMAIL);
final String commentContent = comment.getString(Comment.COMMENT_CONTENT).
replaceAll(SoloServletListener.ENTER_ESC, "<br/>");
final String commentContent = comment.getString(Comment.COMMENT_CONTENT).replaceAll(SoloServletListener.ENTER_ESC, "<br/>");
final String commentSharpURL = comment.getString(Comment.COMMENT_SHARP_URL);
final Message message = new Message();
message.setFrom(adminEmail);
message.addRecipient(originalCommentEmail);
final JSONObject replyNotificationTemplate = preferenceQueryService.getReplyNotificationTemplate();
final String mailSubject = replyNotificationTemplate.getString("subject").replace("${blogTitle}", blogTitle);
message.setSubject(mailSubject);
final String pageTitle = page.getString(Page.PAGE_TITLE);
final String blogHost = preference.getString(Preference.BLOG_HOST);
......@@ -105,22 +115,19 @@ public final class PageCommentReplyNotifier extends AbstractEventListener<JSONOb
final String commentName = comment.getString(Comment.COMMENT_NAME);
final String commentURL = comment.getString(Comment.COMMENT_URL);
String commenter;
if (!"http://".equals(commentURL)) {
commenter = "<a target=\"_blank\" " + "href=\"" + commentURL + "\">" + commentName + "</a>";
} else {
commenter = commentName;
}
final String mailBody = replyNotificationTemplate.getString("body").
replace("${postLink}", pageLink).
replace("${postTitle}", pageTitle).
replace("${replier}", commenter).
replace("${replyURL}", "http://" + blogHost
+ commentSharpURL).
replace("${replyContent}", commentContent);
final String mailBody = replyNotificationTemplate.getString("body").replace("${postLink}", pageLink).replace("${postTitle}", pageTitle).replace("${replier}", commenter).replace("${replyURL}", "http://" + blogHost + commentSharpURL).replace(
"${replyContent}", commentContent);
message.setHtmlBody(mailBody);
LOGGER.log(Level.FINER, "Sending a mail[mailSubject={0}, mailBody=[{1}] to [{2}]",
new Object[]{mailSubject, mailBody, originalCommentEmail});
new Object[] {mailSubject, mailBody, originalCommentEmail});
mailService.send(message);
} catch (final Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.event.ping;
import java.net.URL;
import java.net.URLEncoder;
import java.util.logging.Level;
......@@ -32,6 +33,7 @@ import org.b3log.solo.model.Preference;
import org.b3log.solo.service.PreferenceQueryService;
import org.json.JSONObject;
/**
* This listener is responsible for pinging <a href="http://blogsearch.google.com">
* Google Blog Search Service</a> asynchronously while adding an article.
......@@ -54,6 +56,7 @@ public final class AddArticleGoogleBlogSearchPinger extends AbstractEventListene
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(AddArticleGoogleBlogSearchPinger.class.getName());
/**
* URL fetch service.
*/
......@@ -74,28 +77,31 @@ public final class AddArticleGoogleBlogSearchPinger extends AbstractEventListene
final JSONObject eventData = event.getData();
String articleTitle = null;
try {
final JSONObject article = eventData.getJSONObject(Article.ARTICLE);
articleTitle = article.getString(Article.ARTICLE_TITLE);
final JSONObject preference = PreferenceQueryService.getInstance().getPreference();
final String blogTitle = preference.getString(Preference.BLOG_TITLE);
String blogHost = preference.getString(Preference.BLOG_HOST).
toLowerCase().trim();
String blogHost = preference.getString(Preference.BLOG_HOST).toLowerCase().trim();
if ("localhost".equals(blogHost.split(":")[0].trim())) {
LOGGER.log(Level.INFO, "Blog Solo runs on local server, so should not ping "
+ "Google Blog Search Service for the article[title={0}]",
new Object[]{article.getString(Article.ARTICLE_TITLE)});
LOGGER.log(Level.INFO,
"Blog Solo runs on local server, so should not ping " + "Google Blog Search Service for the article[title={0}]",
new Object[] {article.getString(Article.ARTICLE_TITLE)});
return;
}
blogHost = StringUtils.removeEnd("http://" + blogHost, "/");
final String articlePermalink = blogHost + article.getString(Article.ARTICLE_PERMALINK);
final String spec = "http://blogsearch.google.com/ping?name="
+ URLEncoder.encode(blogTitle, "UTF-8") + "&url=" + URLEncoder.encode(blogHost, "UTF-8")
+ "&changesURL=" + URLEncoder.encode(articlePermalink, "UTF-8");
LOGGER.log(Level.FINER, "Request Google Blog Search Service API[{0}] while adding an "
+ "article[title=" + articleTitle + "]", spec);
final String spec = "http://blogsearch.google.com/ping?name=" + URLEncoder.encode(blogTitle, "UTF-8") + "&url="
+ URLEncoder.encode(blogHost, "UTF-8") + "&changesURL=" + URLEncoder.encode(articlePermalink, "UTF-8");
LOGGER.log(Level.FINER, "Request Google Blog Search Service API[{0}] while adding an " + "article[title=" + articleTitle + "]",
spec);
final HTTPRequest request = new HTTPRequest();
request.setURL(new URL(spec));
URL_FETCH_SERVICE.fetchAsync(request);
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.event.ping;
import java.net.URL;
import java.net.URLEncoder;
import java.util.logging.Level;
......@@ -32,6 +33,7 @@ import org.b3log.solo.model.Preference;
import org.b3log.solo.service.PreferenceQueryService;
import org.json.JSONObject;
/**
* This listener is responsible for pinging <a href="http://blogsearch.google.com">
* Google Blog Search Service</a> asynchronously while updating an article.
......@@ -48,13 +50,13 @@ import org.json.JSONObject;
* @see AddArticleGoogleBlogSearchPinger
* @since 0.3.1
*/
public final class UpdateArticleGoogleBlogSearchPinger
extends AbstractEventListener<JSONObject> {
public final class UpdateArticleGoogleBlogSearchPinger extends AbstractEventListener<JSONObject> {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(UpdateArticleGoogleBlogSearchPinger.class.getName());
/**
* URL fetch service.
*/
......@@ -75,27 +77,31 @@ public final class UpdateArticleGoogleBlogSearchPinger
final JSONObject eventData = event.getData();
String articleTitle = null;
try {
final JSONObject article = eventData.getJSONObject(Article.ARTICLE);
articleTitle = article.getString(Article.ARTICLE_TITLE);
final JSONObject preference = PreferenceQueryService.getInstance().getPreference();
final String blogTitle = preference.getString(Preference.BLOG_TITLE);
String blogHost = preference.getString(Preference.BLOG_HOST).toLowerCase().trim();
if ("localhost".equals(blogHost.split(":")[0].trim())) {
LOGGER.log(Level.INFO, "Blog Solo runs on local server, so should not ping "
+ "Google Blog Search Service for the article[title={0}]",
new Object[]{article.getString(Article.ARTICLE_TITLE)});
LOGGER.log(Level.INFO,
"Blog Solo runs on local server, so should not ping " + "Google Blog Search Service for the article[title={0}]",
new Object[] {article.getString(Article.ARTICLE_TITLE)});
return;
}
blogHost = StringUtils.removeEnd("http://" + blogHost, "/");
final String articlePermalink = blogHost + article.getString(Article.ARTICLE_PERMALINK);
final String spec = "http://blogsearch.google.com/ping?name=" + URLEncoder.encode(blogTitle, "UTF-8")
+ "&url=" + URLEncoder.encode(blogHost, "UTF-8")
+ "&changesURL=" + URLEncoder.encode(articlePermalink, "UTF-8");
LOGGER.log(Level.FINER, "Request Google Blog Search Service API[{0}] while updateing "
+ "an article[title=" + articleTitle + "]", spec);
final String spec = "http://blogsearch.google.com/ping?name=" + URLEncoder.encode(blogTitle, "UTF-8") + "&url="
+ URLEncoder.encode(blogHost, "UTF-8") + "&changesURL=" + URLEncoder.encode(articlePermalink, "UTF-8");
LOGGER.log(Level.FINER,
"Request Google Blog Search Service API[{0}] while updateing " + "an article[title=" + articleTitle + "]", spec);
final HTTPRequest request = new HTTPRequest();
request.setURL(new URL(spec));
URL_FETCH_SERVICE.fetchAsync(request);
} catch (final Exception e) {
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.event.plugin;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -28,6 +29,7 @@ import org.b3log.solo.repository.PluginRepository;
import org.b3log.solo.repository.impl.PluginRepositoryImpl;
import org.b3log.solo.util.Plugins;
/**
* This listener is responsible for refreshing plugin after every loaded.
*
......@@ -40,25 +42,23 @@ public final class PluginRefresher extends AbstractEventListener<List<AbstractPl
/**
* Logger.
*/
private static final Logger LOGGER =
Logger.getLogger(PluginRefresher.class.getName());
private static final Logger LOGGER = Logger.getLogger(PluginRefresher.class.getName());
/**
* Plugin repository.
*/
private PluginRepository pluginRepository =
PluginRepositoryImpl.getInstance();
private PluginRepository pluginRepository = PluginRepositoryImpl.getInstance();
@Override
public void action(final Event<List<AbstractPlugin>> event) throws
EventException {
final List<AbstractPlugin> plugins = event.getData();
LOGGER.log(Level.FINER,
"Processing an event[type={0}, data={1}] in listener[className={2}]",
new Object[]{event.getType(), plugins,
PluginRefresher.class.getName()});
LOGGER.log(Level.FINER, "Processing an event[type={0}, data={1}] in listener[className={2}]",
new Object[] {event.getType(), plugins, PluginRefresher.class.getName()});
final Transaction transaction = pluginRepository.beginTransaction();
transaction.clearQueryCache(false);
try {
Plugins.refresh(plugins);
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.event.rhythm;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
......@@ -38,6 +39,7 @@ import org.b3log.solo.model.Preference;
import org.b3log.solo.service.PreferenceQueryService;
import org.json.JSONObject;
/**
* This listener is responsible for sending article to B3log Rhythm.
*
......@@ -52,18 +54,22 @@ public final class ArticleSender extends AbstractEventListener<JSONObject> {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(ArticleSender.class.getName());
/**
* URL fetch service.
*/
private final URLFetchService urlFetchService = URLFetchServiceFactory.getURLFetchService();
/**
* Preference query service.
*/
private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance();
/**
* B3log Rhythm address.
*/
public static final String B3LOG_RHYTHM_ADDRESS = "http://rhythm.b3log.org:80";
/**
* URL of adding article to Rhythm.
*/
......@@ -81,10 +87,12 @@ public final class ArticleSender extends AbstractEventListener<JSONObject> {
@Override
public void action(final Event<JSONObject> event) throws EventException {
final JSONObject data = event.getData();
LOGGER.log(Level.FINER, "Processing an event[type={0}, data={1}] in listener[className={2}]",
new Object[]{event.getType(), data, ArticleSender.class.getName()});
new Object[] {event.getType(), data, ArticleSender.class.getName()});
try {
final JSONObject originalArticle = data.getJSONObject(Article.ARTICLE);
if (!originalArticle.getBoolean(Article.ARTICLE_IS_PUBLISHED)) {
LOGGER.log(Level.FINER, "Ignores post article[title={0}] to Rhythm", originalArticle.getString(Article.ARTICLE_TITLE));
......@@ -92,6 +100,7 @@ public final class ArticleSender extends AbstractEventListener<JSONObject> {
}
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) {
throw new EventException("Not found preference");
}
......@@ -99,17 +108,20 @@ public final class ArticleSender extends AbstractEventListener<JSONObject> {
// Use configured host if Preference.BLOG_HOST is empty.
final String perferHost = preference.getString(Preference.BLOG_HOST);
final String blogHost = !Strings.isEmptyOrNull(perferHost) ? perferHost.toLowerCase() : Latkes.getServePath().toLowerCase();
if (blogHost.contains("localhost")) {
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;
}
final HTTPRequest httpRequest = new HTTPRequest();
httpRequest.setURL(ADD_ARTICLE_URL);
httpRequest.setRequestMethod(HTTPRequestMethod.POST);
final JSONObject requestJSONObject = new JSONObject();
final JSONObject article = new JSONObject();
article.put(Keys.OBJECT_ID, originalArticle.getString(Keys.OBJECT_ID));
article.put(Article.ARTICLE_TITLE, originalArticle.getString(Article.ARTICLE_TITLE));
article.put(Article.ARTICLE_PERMALINK, originalArticle.getString(Article.ARTICLE_PERMALINK));
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.event.symphony;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
......@@ -36,6 +37,7 @@ import org.b3log.solo.model.Preference;
import org.b3log.solo.service.PreferenceQueryService;
import org.json.JSONObject;
/**
* This listener is responsible for sending comment to B3log Symphony.
*
......@@ -49,18 +51,22 @@ public final class CommentSender extends AbstractEventListener<JSONObject> {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(CommentSender.class.getName());
/**
* URL fetch service.
*/
private final URLFetchService urlFetchService = URLFetchServiceFactory.getURLFetchService();
/**
* Preference query service.
*/
private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance();
/**
* B3log Symphony address.
*/
public static final String B3LOG_SYMPHONY_ADDRESS = "http://symphony.b3log.org:80";
/**
* URL of adding comment to Symphony.
*/
......@@ -78,28 +84,33 @@ public final class CommentSender extends AbstractEventListener<JSONObject> {
@Override
public void action(final Event<JSONObject> event) throws EventException {
final JSONObject data = event.getData();
LOGGER.log(Level.FINER, "Processing an event[type={0}, data={1}] in listener[className={2}]",
new Object[]{event.getType(), data, ArticleSender.class.getName()});
new Object[] {event.getType(), data, ArticleSender.class.getName()});
try {
final JSONObject originalComment = data.getJSONObject(Comment.COMMENT);
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) {
throw new EventException("Not found preference");
}
final String blogHost = preference.getString(Preference.BLOG_HOST).toLowerCase();
if (blogHost.contains("localhost")) {
LOGGER.log(Level.INFO, "Blog Solo runs on local server, so should not send this comment[id={0}] to Symphony",
new Object[]{originalComment.getString(Keys.OBJECT_ID)});
new Object[] {originalComment.getString(Keys.OBJECT_ID)});
return;
}
final HTTPRequest httpRequest = new HTTPRequest();
httpRequest.setURL(ADD_COMMENT_URL);
httpRequest.setRequestMethod(HTTPRequestMethod.PUT);
final JSONObject requestJSONObject = new JSONObject();
final JSONObject comment = new JSONObject();
comment.put("commentId", originalComment.optString(Keys.OBJECT_ID));
comment.put("commentAuthorName", originalComment.getString(Comment.COMMENT_NAME));
comment.put("commentAuthorEmail", originalComment.getString(Comment.COMMENT_EMAIL));
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.filter;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.IOException;
......@@ -32,6 +33,7 @@ import org.b3log.latke.user.UserServiceFactory;
import org.b3log.solo.processor.LoginProcessor;
import org.b3log.solo.util.Users;
/**
* Authentication filter.
*
......@@ -45,18 +47,19 @@ public final class AuthFilter implements Filter {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(AuthFilter.class.getName());
/**
* User service.
*/
private UserService userService = UserServiceFactory.getUserService();
/**
* User utilities.
*/
private Users users = Users.getInstance();
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
public void init(final FilterConfig filterConfig) throws ServletException {}
/**
* If the specified request is NOT made by an authenticated user, sends
......@@ -80,6 +83,7 @@ public final class AuthFilter implements Filter {
LoginProcessor.tryLogInWithCookie(httpServletRequest, httpServletResponse);
final GeneralUser currentUser = userService.getCurrentUser(httpServletRequest);
if (null == currentUser) {
LOGGER.warning("The request has been forbidden");
httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
......@@ -88,6 +92,7 @@ public final class AuthFilter implements Filter {
}
final String currentUserEmail = currentUser.getEmail();
LOGGER.log(Level.FINER, "Current user email[{0}]", currentUserEmail);
if (users.isSoloUser(currentUserEmail)) {
chain.doFilter(request, response);
......@@ -103,6 +108,5 @@ public final class AuthFilter implements Filter {
}
@Override
public void destroy() {
}
public void destroy() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.filter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -36,6 +37,7 @@ import org.b3log.solo.SoloServletListener;
import org.b3log.solo.service.PreferenceQueryService;
import org.json.JSONObject;
/**
* Checks initialization filter.
*
......@@ -49,14 +51,14 @@ public final class InitCheckFilter implements Filter {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(InitCheckFilter.class.getName());
/**
* Preference query service.
*/
private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance();
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
public void init(final FilterConfig filterConfig) throws ServletException {}
/**
* If Solo has not been initialized, so redirects to /init.
......@@ -72,6 +74,7 @@ public final class InitCheckFilter implements Filter {
throws IOException, ServletException {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final String requestURI = httpServletRequest.getRequestURI();
LOGGER.log(Level.FINEST, "Request[URI={0}]", requestURI);
if (requestURI.startsWith("/latke/remote")) {
......@@ -88,8 +91,7 @@ public final class InitCheckFilter implements Filter {
return;
}
if ("POST".equalsIgnoreCase(httpServletRequest.getMethod())
&& (Latkes.getContextPath() + "/init").equals(requestURI)) {
if ("POST".equalsIgnoreCase(httpServletRequest.getMethod()) && (Latkes.getContextPath() + "/init").equals(requestURI)) {
// Do initailization
chain.doFilter(request, response);
......@@ -98,10 +100,12 @@ public final class InitCheckFilter implements Filter {
LOGGER.finer("Try to get preference to confirm whether the preference exixts");
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) {
LOGGER.log(Level.WARNING, "B3log Solo has not been initialized, so redirects to /init");
final HTTPRequestContext context = new HTTPRequestContext();
context.setRequest((HttpServletRequest) request);
context.setResponse((HttpServletResponse) response);
......@@ -114,12 +118,10 @@ public final class InitCheckFilter implements Filter {
chain.doFilter(request, response);
}
} catch (final ServiceException e) {
((HttpServletResponse) response).sendError(
HttpServletResponse.SC_NOT_FOUND);
((HttpServletResponse) response).sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
@Override
public void destroy() {
}
public void destroy() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.filter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
......@@ -47,6 +48,7 @@ import org.b3log.solo.util.Statistics;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Page cache filter.
*
......@@ -60,26 +62,29 @@ public final class PageCacheFilter implements Filter {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(PageCacheFilter.class.getName());
/**
* Statistic utilities.
*/
private Statistics statistics = Statistics.getInstance();
/**
* Article repository.
*/
private ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance();
/**
* Language service.
*/
private LangPropsService langPropsService = LangPropsService.getInstance();
/**
* Article utilities.
*/
private Articles articles = Articles.getInstance();
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
public void init(final FilterConfig filterConfig) throws ServletException {}
/**
* Try to write response from cache.
......@@ -94,14 +99,17 @@ public final class PageCacheFilter implements Filter {
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.FINER, "Request URI[{0}]", requestURI);
if (StaticResources.isStatic(httpServletRequest)) {
final String path = httpServletRequest.getServletPath() + httpServletRequest.getPathInfo();
LOGGER.log(Level.FINEST, "Requests a static resource, forwards to servlet[path={0}]", path);
request.getRequestDispatcher(path).forward(request, response);
......@@ -116,6 +124,7 @@ public final class PageCacheFilter implements Filter {
}
final String skinDirName = (String) httpServletRequest.getAttribute(Keys.TEMAPLTE_DIR_NAME);
if ("mobile".equals(skinDirName)) {
// Mobile request, bypasses page caching
chain.doFilter(request, response);
......@@ -125,6 +134,7 @@ public final class PageCacheFilter implements Filter {
String pageCacheKey;
final String queryString = httpServletRequest.getQueryString();
pageCacheKey = (String) request.getAttribute(Keys.PAGE_CACHE_KEY);
if (Strings.isEmptyOrNull(pageCacheKey)) {
pageCacheKey = PageCaches.getPageCacheKey(requestURI, queryString);
......@@ -157,9 +167,10 @@ public final class PageCacheFilter implements Filter {
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));
httpServletResponse.sendRedirect(
Latkes.getServePath() + "/console/article-pwd?articleId=" + article.optString(Keys.OBJECT_ID));
return;
} catch (final Exception e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
......@@ -179,18 +190,19 @@ public final class PageCacheFilter implements Filter {
final PrintWriter writer = response.getWriter();
String cachedPageContent = cachedPageContentObject.getString(PageCaches.CACHED_CONTENT);
final String topBarHTML = TopBars.getTopBarHTML((HttpServletRequest) request, (HttpServletResponse) response);
cachedPageContent = cachedPageContent.replace(Common.TOP_BAR_REPLACEMENT_FLAG, topBarHTML);
cachedPageContent = cachedPageContent.replace(Common.TOP_BAR_REPLACEMENT_FLAG, topBarHTML);
final String cachedTitle = cachedPageContentObject.getString(PageCaches.CACHED_TITLE);
LOGGER.log(Level.FINEST, "Cached value[key={0}, type={1}, title={2}]",
new Object[]{pageCacheKey, cachedType, cachedTitle});
LOGGER.log(Level.FINEST, "Cached value[key={0}, type={1}, title={2}]", new Object[] {pageCacheKey, cachedType, cachedTitle});
statistics.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.finer(msg);
cachedPageContent += Strings.LINE_SEPARATOR + msg;
writer.write(cachedPageContent);
......@@ -209,6 +221,5 @@ public final class PageCacheFilter implements Filter {
}
@Override
public void destroy() {
}
public void destroy() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.filter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -43,6 +44,7 @@ import org.b3log.solo.util.Articles;
import org.b3log.solo.util.Permalinks;
import org.json.JSONObject;
/**
* Article/Page permalink filter.
*
......@@ -59,22 +61,24 @@ public final class PermalinkFilter implements Filter {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(PermalinkFilter.class.getName());
/**
* Article repository.
*/
private ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance();
/**
* Page repository.
*/
private PageRepository pageRepository = PageRepositoryImpl.getInstance();
/**
* Article utilities.
*/
private Articles articles = Articles.getInstance();
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
public void init(final FilterConfig filterConfig) throws ServletException {}
/**
* Tries to dispatch request to article processor.
......@@ -92,6 +96,7 @@ public final class PermalinkFilter implements Filter {
final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
final String requestURI = httpServletRequest.getRequestURI();
LOGGER.log(Level.FINER, "Request URI[{0}]", requestURI);
final String contextPath = Latkes.getContextPath();
......@@ -106,6 +111,7 @@ public final class PermalinkFilter implements Filter {
JSONObject article;
JSONObject page = null;
try {
article = articleRepository.getByPermalink(permalink);
if (null == article) {
......@@ -128,8 +134,8 @@ public final class PermalinkFilter implements Filter {
// If requests an article and the article need view passowrd, sends redirect to the password form
if (null != article && articles.needViewPwd(httpServletRequest, article)) {
try {
httpServletResponse.sendRedirect(Latkes.getServePath()
+ "/console/article-pwd?articleId=" + article.optString(Keys.OBJECT_ID));
httpServletResponse.sendRedirect(
Latkes.getServePath() + "/console/article-pwd?articleId=" + article.optString(Keys.OBJECT_ID));
return;
} catch (final Exception e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
......@@ -156,6 +162,7 @@ public final class PermalinkFilter implements Filter {
final JSONObject article, final JSONObject page)
throws ServletException, IOException {
final HTTPRequestContext context = new HTTPRequestContext();
context.setRequest((HttpServletRequest) request);
context.setResponse((HttpServletResponse) response);
......@@ -173,6 +180,5 @@ public final class PermalinkFilter implements Filter {
}
@Override
public void destroy() {
}
public void destroy() {}
}
......@@ -15,9 +15,11 @@
*/
package org.b3log.solo.model;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/**
* This class defines all archive date model relevant keys.
*
......@@ -30,41 +32,44 @@ public final class ArchiveDate {
* Archive date.
*/
public static final String ARCHIVE_DATE = "archiveDate";
/**
* Archive dates.
*/
public static final String ARCHIVE_DATES = "archiveDates";
/**
* Archive time.
*/
public static final String ARCHIVE_TIME = "archiveTime";
/**
* Key of archive date article count.
*/
public static final String ARCHIVE_DATE_ARTICLE_COUNT =
"archiveDateArticleCount";
public static final String ARCHIVE_DATE_ARTICLE_COUNT = "archiveDateArticleCount";
/**
* Key of archive date article count.
*/
public static final String ARCHIVE_DATE_PUBLISHED_ARTICLE_COUNT =
"archiveDatePublishedArticleCount";
public static final String ARCHIVE_DATE_PUBLISHED_ARTICLE_COUNT = "archiveDatePublishedArticleCount";
/**
* Archive date year.
*/
public static final String ARCHIVE_DATE_YEAR = "archiveDateYear";
/**
* Archive date month.
*/
public static final String ARCHIVE_DATE_MONTH = "archiveDateMonth";
/**
* Date format(yyyy/MM).
*/
public static final DateFormat DATE_FORMAT =
new SimpleDateFormat("yyyy/MM");
public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM");
/**
* Private default constructor.
*/
private ArchiveDate() {
}
private ArchiveDate() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model;
/**
* This class defines all article model relevant keys.
*
......@@ -28,90 +29,112 @@ public final class Article {
* Article.
*/
public static final String ARTICLE = "article";
/**
* Articles.
*/
public static final String ARTICLES = "articles";
/**
* Key of title.
*/
public static final String ARTICLE_TITLE = "articleTitle";
/**
* Key of abstract.
*/
public static final String ARTICLE_ABSTRACT = "articleAbstract";
/**
* Key of content.
*/
public static final String ARTICLE_CONTENT = "articleContent";
/**
* Key of create date.
*/
public static final String ARTICLE_CREATE_DATE = "articleCreateDate";
/**
* Key of create time.
*/
public static final String ARTICLE_CREATE_TIME = "articleCreateTime";
/**
* Key of update date.
*/
public static final String ARTICLE_UPDATE_DATE = "articleUpdateDate";
/**
* Key of update time.
*/
public static final String ARTICLE_UPDATE_TIME = "articleUpdateTime";
/**
* Key of tags.
*/
public static final String ARTICLE_TAGS_REF = "articleTags";
/**
* Key of comment count.
*/
public static final String ARTICLE_COMMENT_COUNT = "articleCommentCount";
/**
* Key of view count.
*/
public static final String ARTICLE_VIEW_COUNT = "articleViewCount";
/**
* Key of comments.
*/
public static final String ARTICLE_COMMENTS_REF = "articleComments";
/**
* Key of sign id.
*/
public static final String ARTICLE_SIGN_ID = "articleSignId";
/**
* Key of permalink.
*/
public static final String ARTICLE_PERMALINK = "articlePermalink";
/**
* Key of put top.
*/
public static final String ARTICLE_PUT_TOP = "articlePutTop";
/**
* Key of is published.
*/
public static final String ARTICLE_IS_PUBLISHED = "articleIsPublished";
/**
* Key of author email.
*/
public static final String ARTICLE_AUTHOR_EMAIL = "articleAuthorEmail";
/**
* Key of had been published.
*/
public static final String ARTICLE_HAD_BEEN_PUBLISHED = "articleHadBeenPublished";
/**
* Key of random double.
*/
public static final String ARTICLE_RANDOM_DOUBLE = "articleRandomDouble";
/**
* Key of comment-able.
*/
public static final String ARTICLE_COMMENTABLE = "articleCommentable";
/**
* Key of view password.
*/
public static final String ARTICLE_VIEW_PWD = "articleViewPwd";
/**
* Key of article editor type.
*
......@@ -122,6 +145,5 @@ public final class Article {
/**
* Private default constructor.
*/
private Article() {
}
private Article() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model;
/**
* This class defines all cache model relevant keys.
*
......@@ -27,22 +28,27 @@ 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.
*/
......@@ -51,6 +57,5 @@ public final class Cache {
/**
* Private default constructor.
*/
private Cache() {
}
private Cache() {}
}
......@@ -15,9 +15,11 @@
*/
package org.b3log.solo.model;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/**
* This class defines all comment model relevant keys.
*
......@@ -31,69 +33,79 @@ public final class Comment {
* Comment.
*/
public static final String COMMENT = "comment";
/**
* Comments.
*/
public static final String COMMENTS = "comments";
/**
* Key of comment.
*/
public static final String COMMENT_CONTENT = "commentContent";
/**
* Key of comment name.
*/
public static final String COMMENT_NAME = "commentName";
/**
* Key of comment email.
*/
public static final String COMMENT_EMAIL = "commentEmail";
/**
* Key of comment URL.
*/
public static final String COMMENT_URL = "commentURL";
/**
* Key of comment sharp URL.
*/
public static final String COMMENT_SHARP_URL = "commentSharpURL";
/**
* Key of comment date.
*/
public static final String COMMENT_DATE = "commentDate";
/**
* Key of comment time.
*/
public static final String COMMENT_TIME = "commentTime";
/**
* Key of comment thumbnail URL.
*/
public static final String COMMENT_THUMBNAIL_URL = "commentThumbnailURL";
/**
* Key of original comment id.
*/
public static final String COMMENT_ORIGINAL_COMMENT_ID =
"commentOriginalCommentId";
public static final String COMMENT_ORIGINAL_COMMENT_ID = "commentOriginalCommentId";
/**
* Key of original comment user name.
*/
public static final String COMMENT_ORIGINAL_COMMENT_NAME =
"commentOriginalCommentName";
public static final String COMMENT_ORIGINAL_COMMENT_NAME = "commentOriginalCommentName";
/**
* Key of comment on type.
*/
public static final String COMMENT_ON_TYPE = "commentOnType";
/**
* Key of comment on id.
*/
public static final String COMMENT_ON_ID = "commentOnId";
/**
* Date format(yyyy/MM/dd hh:mm:ss).
*/
public static final DateFormat DATE_FORMAT =
new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
/**
* Private default constructor.
*/
private Comment() {
}
private Comment() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model;
/**
* This class defines all common model relevant keys.
*
......@@ -29,218 +30,272 @@ public final class Common {
* Key of direction.
*/
public static final String DIRECTION = "direction";
/**
* Most used tags.
*/
public static final String MOST_USED_TAGS = "mostUsedTags";
/**
* Most comment count articles.
*/
public static final String MOST_COMMENT_ARTICLES = "mostCommentArticles";
/**
* Most view count articles.
*/
public static final String MOST_VIEW_COUNT_ARTICLES = "mostViewCountArticles";
/**
* Recent articles.
*/
public static final String RECENT_ARTICLES = "recentArticles";
/**
* Recent comments.
*/
public static final String RECENT_COMMENTS = "recentComments";
/**
* Previous article permalink.
*/
public static final String PREVIOUS_ARTICLE_PERMALINK = "previousArticlePermalink";
/**
* Next article permalink.
*/
public static final String NEXT_ARTICLE_PERMALINK = "nextArticlePermalink";
/**
* Previous article title.
*/
public static final String PREVIOUS_ARTICLE_TITLE = "previousArticleTitle";
/**
* Next article title.
*/
public static final String NEXT_ARTICLE_TITLE = "nextArticleTitle";
/**
* index.
*/
public static final String INDEX = "index";
/**
* tag-articles.
*/
public static final String TAG_ARTICLES = "tag-articles";
/**
* archive-date-articles.
*/
public static final String ARCHIVED_DATE_ARTICLES = "archive-date-articles";
/**
* author-articles.
*/
public static final String AUTHOR_ARTICLES = "author-articles";
/**
* Key of path.
*/
public static final String PATH = "path";
/**
* Version.
*/
public static final String VERSION = "version";
/**
* Static resource version.
*/
public static final String STATIC_RESOURCE_VERSION = "staticResourceVersion";
/**
* Year.
*/
public static final String YEAR = "year";
/**
* Key of flag a comment is an reply or not.
*/
public static final String IS_REPLY = "isReply";
/**
* Key of page navigations.
*/
public static final String PAGE_NAVIGATIONS = "pageNavigations";
/**
* Key of relevant articles.
*/
public static final String RELEVANT_ARTICLES = "relevantArticles";
/**
* Key of random articles.
*/
public static final String RANDOM_ARTICLES = "randomArticles";
/**
* Key of has updated.
*/
public static final String HAS_UPDATED = "hasUpdated";
/**
* Author name.
*/
public static final String AUTHOR_NAME = "authorName";
/**
* Author id.
*/
public static final String AUTHOR_ID = "authorId";
/**
* Author role.
*/
public static final String AUTHOR_ROLE = "authorRole";
/**
* Key of current user.
*/
public static final String CURRENT_USER = "currentUser";
/**
* Key of enabled multiple user support.
*/
public static final String ENABLED_MULTIPLE_USER_SUPPORT = "enabledMultipleUserSupport";
/**
* Key of is logged in.
*/
public static final String IS_LOGGED_IN = "isLoggedIn";
/**
* Key of is mobile request.
*/
public static final String IS_MOBILE_REQUEST = "isMobileRequest";
/**
* Key of login URL.
*/
public static final String LOGIN_URL = "loginURL";
/**
* Key of logout URL.
*/
public static final String LOGOUT_URL = "logoutURL";
/**
* Key of is administrator.
*/
public static final String IS_ADMIN = "isAdmin";
/**
* Key of URI.
*/
public static final String URI = "URI";
/**
* Key of blog.
*/
public static final String BLOG = "blog";
/**
* Key of blog version.
*/
public static final String BLOG_VERSION = "blogVersion";
/**
* Key of post to community.
*/
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.
*/
public static final String MINI_POSTFIX = "miniPostfix";
/**
* Value of mini postfix.
*/
public static final String MINI_POSTFIX_VALUE = ".min";
/**
* Key of month name.
*/
public static final String MONTH_NAME = "monthName";
/**
* Key of comment title (article/page).
*/
public static final String COMMENT_TITLE = "commentTitle";
/**
* /admin-index.do#main.
*/
public static final String ADMIN_INDEX_URI = "/admin-index.do#main";
/**
* Key of type.
*/
public static final String TYPE = "type";
/**
* Article comment type.
*/
public static final String ARTICLE_COMMENT_TYPE = "articleComment";
/**
* Page comment type.
*/
public static final String PAGE_COMMENT_TYPE = "pageComment";
/**
* Key of top bar replacement flag.
*/
public static final String TOP_BAR_REPLACEMENT_FLAG_KEY = "topBarReplacement";
/**
* Top bar replacement flag.
*/
public static final String TOP_BAR_REPLACEMENT_FLAG = "#B3logSolo#topBarReplacement#B3logSolo#";
/**
* Key of unused tags.
*/
public static final String UNUSED_TAGS = "unusedTags";
/**
* Key of go to.
*/
public static final String GOTO = "goto";
/**
* Key of online visitor count.
*/
public static final String ONLINE_VISITOR_CNT = "onlineVisitorCnt";
/**
* Key of article sign.
*/
public static final String ARTICLE_SIGN = "articleSign";
/**
* Key of permalink.
*/
public static final String PERMALINK = "permalink";
/**
* Key of commentable.
*/
public static final String COMMENTABLE = "commentable";
/**
* Key of articles view password.
*/
......@@ -249,6 +304,5 @@ public final class Common {
/**
* Private default constructor.
*/
private Common() {
}
private Common() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model;
/**
* This class defines all link model relevant keys.
*
......@@ -28,22 +29,27 @@ public final class Link {
* Link.
*/
public static final String LINK = "link";
/**
* Links.
*/
public static final String LINKS = "links";
/**
* Key of title.
*/
public static final String LINK_TITLE = "linkTitle";
/**
* Key of address.
*/
public static final String LINK_ADDRESS = "linkAddress";
/**
* Key of description.
*/
public static final String LINK_DESCRIPTION = "linkDescription";
/**
* Key of order.
*/
......@@ -52,6 +58,5 @@ public final class Link {
/**
* Private default constructor.
*/
private Link() {
}
private Link() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model;
/**
* This class defines all page model relevant keys.
*
......@@ -28,38 +29,47 @@ public final class Page {
* Page.
*/
public static final String PAGE = "page";
/**
* Pages.
*/
public static final String PAGES = "pages";
/**
* Key of title.
*/
public static final String PAGE_TITLE = "pageTitle";
/**
* Key of content.
*/
public static final String PAGE_CONTENT = "pageContent";
/**
* Key of order.
*/
public static final String PAGE_ORDER = "pageOrder";
/**
* Key of comment count.
*/
public static final String PAGE_COMMENT_COUNT = "pageCommentCount";
/**
* Key of permalink.
*/
public static final String PAGE_PERMALINK = "pagePermalink";
/**
* Key of comments.
*/
public static final String PAGE_COMMENTS_REF = "pageComments";
/**
* Key of comment-able.
*/
public static final String PAGE_COMMENTABLE = "pageCommentable";
/**
* Key of page type.
*
......@@ -74,6 +84,7 @@ public final class Page {
* </p>
*/
public static final String PAGE_TYPE = "pageType";
/**
* Key of open target.
*
......@@ -95,6 +106,7 @@ public final class Page {
* </p>
*/
public static final String PAGE_OPEN_TARGET = "pageOpenTarget";
/**
* Key of page editor type.
*
......@@ -105,6 +117,5 @@ public final class Page {
/**
* Private default constructor.
*/
private Page() {
}
private Page() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model;
/**
* This class defines all sign model relevant keys.
*
......@@ -27,10 +28,12 @@ public final class Sign {
* Key of sign.
*/
public static final String SIGN = "sign";
/**
* Key of signs.
*/
public static final String SIGNS = "signs";
/**
* Key of sign HTML.
*/
......@@ -39,6 +42,5 @@ public final class Sign {
/**
* Private default constructor.
*/
private Sign() {
}
private Sign() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model;
/**
* This class defines all skin model relevant keys.
*
......@@ -27,18 +28,22 @@ public final class Skin {
* Skin.
*/
public static final String SKIN = "skin";
/**
* Skins.
*/
public static final String SKINS = "skins";
/**
* Key of skin name, current selected skin name.
*/
public static final String SKIN_NAME = "skinName";
/**
* Key of skin names.
*/
public static final String SKIN_NAMES = "skinNames";
/**
* Key of skin directory name.
*/
......@@ -47,6 +52,5 @@ public final class Skin {
/**
* Private default constructor.
*/
private Skin() {
}
private Skin() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model;
/**
* This class defines all statistic model relevant keys.
*
......@@ -27,35 +28,34 @@ public final class Statistic {
* Statistic.
*/
public static final String STATISTIC = "statistic";
/**
* Key of blog view count.
*/
public static final String STATISTIC_BLOG_VIEW_COUNT =
"statisticBlogViewCount";
public static final String STATISTIC_BLOG_VIEW_COUNT = "statisticBlogViewCount";
/**
* Key of blog comment count.
*/
public static final String STATISTIC_BLOG_COMMENT_COUNT =
"statisticBlogCommentCount";
public static final String STATISTIC_BLOG_COMMENT_COUNT = "statisticBlogCommentCount";
/**
* Key of blog comment(published article) count.
*/
public static final String STATISTIC_PUBLISHED_BLOG_COMMENT_COUNT =
"statisticPublishedBlogCommentCount";
public static final String STATISTIC_PUBLISHED_BLOG_COMMENT_COUNT = "statisticPublishedBlogCommentCount";
/**
* Key of blog article count.
*/
public static final String STATISTIC_BLOG_ARTICLE_COUNT =
"statisticBlogArticleCount";
public static final String STATISTIC_BLOG_ARTICLE_COUNT = "statisticBlogArticleCount";
/**
* Key of blog published article count.
*/
public static final String STATISTIC_PUBLISHED_ARTICLE_COUNT =
"statisticPublishedBlogArticleCount";
public static final String STATISTIC_PUBLISHED_ARTICLE_COUNT = "statisticPublishedBlogArticleCount";
/**
* Private default constructor.
*/
private Statistic() {
}
private Statistic() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model;
/**
* This class defines all tag model relevant keys.
*
......@@ -27,27 +28,29 @@ public final class Tag {
* Tag.
*/
public static final String TAG = "tag";
/**
* Tags.
*/
public static final String TAGS = "tags";
/**
* Key of title.
*/
public static final String TAG_TITLE = "tagTitle";
/**
* Key of tag reference count.
*/
public static final String TAG_REFERENCE_COUNT = "tagReferenceCount";
/**
* Key of tag reference(published article) count.
*/
public static final String TAG_PUBLISHED_REFERENCE_COUNT =
"tagPublishedRefCount";
public static final String TAG_PUBLISHED_REFERENCE_COUNT = "tagPublishedRefCount";
/**
* Private default constructor.
*/
private Tag() {
}
private Tag() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model;
/**
* This class defines ext of user model relevant keys.
*
......@@ -29,6 +30,7 @@ public final class UserExt {
* Key of user article count.
*/
public static final String USER_ARTICLE_COUNT = "userArticleCount";
/**
* Key of user article count.
*/
......@@ -37,6 +39,5 @@ public final class UserExt {
/**
* Private constructor.
*/
private UserExt() {
}
private UserExt() {}
}
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model.feed.atom;
/**
* Category.
*
......@@ -28,10 +29,12 @@ public final class Category {
* Term variable.
*/
private static final String TERM_VARIABLE = "${term}";
/**
* Category element.
*/
private static final String CATEGORY_ELEMENT = "<category term=\"" + TERM_VARIABLE + "\" />";
/**
* Term.
*/
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model.feed.atom;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
......@@ -22,6 +23,7 @@ import java.util.Set;
import java.util.TimeZone;
import org.apache.commons.lang.time.DateFormatUtils;
/**
* Entry.
*
......@@ -35,103 +37,127 @@ public final class Entry {
* Link variable.
*/
private static final String LINK_VARIABLE = "${link}";
/**
* Start title element.
*/
private static final String START_TITLE_ELEMENT = "<title type=\"text\">";
/**
* End title element.
*/
private static final String END_TITLE_ELEMENT = "</title>";
/**
* Start author element.
*/
private static final String START_AUTHOR_ELEMENT = "<author>";
/**
* End author element.
*/
private static final String END_AUTHOR_ELEMENT = "</author>";
/**
* Start name element.
*/
private static final String START_NAME_ELEMENT = "<name>";
/**
* End name element.
*/
private static final String END_NAME_ELEMENT = "</name>";
/**
* Start URI element.
*/
private static final String START_URI_ELEMENT = "<uri>";
/**
* End URI element.
*/
private static final String END_URI_ELEMENT = "</uri>";
/**
* Start entry element.
*/
private static final String START_ENTRY_ELEMENT = "<entry>";
/**
* End entry element.
*/
private static final String END_ENTRY_ELEMENT = "</entry>";
/**
* Start id element.
*/
private static final String START_ID_ELEMENT = "<id>";
/**
* End id element.
*/
private static final String END_ID_ELEMENT = "</id>";
/**
* Start summary element.
*/
private static final String START_SUMMARY_ELEMENT = "<summary type=\"html\">";
/**
* End summary element.
*/
private static final String END_SUMMARY_ELEMENT = "</summary>";
/**
* Link element.
*/
private static final String LINK_ELEMENT =
"<link href=\"" + LINK_VARIABLE + "\" />";
private static final String LINK_ELEMENT = "<link href=\"" + LINK_VARIABLE + "\" />";
/**
* Start updated element.
*/
private static final String START_UPDATED_ELEMENT = "<updated>";
/**
* End updated element.
*/
private static final String END_UPDATED_ELEMENT = "</updated>";
/**
* Id.
*/
private String id;
/**
* Update date.
*/
private Date updated;
/**
* Title.
*/
private String title;
/**
* Summary.
*/
private String summary;
/**
* Link.
*/
private String link;
/**
* Author.
*/
private String author;
/**
* URI.
*/
private String uri;
/**
* Categories.
*/
......@@ -298,7 +324,6 @@ public final class Entry {
stringBuilder.append(END_URI_ELEMENT);
stringBuilder.append(END_AUTHOR_ELEMENT);
for (final Category category : categories) {
stringBuilder.append(category.toString());
}
......@@ -311,9 +336,7 @@ public final class Entry {
stringBuilder.append(START_UPDATED_ELEMENT);
stringBuilder.append(DateFormatUtils.format(// using ISO-8601 instead of RFC-3339
updated,
DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(),
TimeZone.getTimeZone(Feed.TIME_ZONE_ID)));
updated, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZone.getTimeZone(Feed.TIME_ZONE_ID)));
stringBuilder.append(END_UPDATED_ELEMENT);
stringBuilder.append(START_SUMMARY_ELEMENT);
......
......@@ -15,12 +15,14 @@
*/
package org.b3log.solo.model.feed.atom;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import org.apache.commons.lang.time.DateFormatUtils;
/**
* Feed.
*
......@@ -41,99 +43,122 @@ public final class Feed {
* Id.
*/
private String id;
/**
* Title.
*/
private String title;
/**
* Subtitle.
*/
private String subtitle;
/**
* Update date.
*/
private Date updated;
/**
* Author.
*/
private String author;
/**
* Link.
*/
private String link;
/**
* Entries.
*/
private List<Entry> entries = new ArrayList<Entry>();
/**
* Link variable.
*/
private static final String LINK_VARIABLE = "${link}";
/**
* Time zone id.
*/
public static final String TIME_ZONE_ID = "Asia/Shanghai";
/**
* Start document.
*/
private static final String START_DOCUMENT = "<?xml version=\"1.0\"?>";
/**
* Start feed element.
*/
private static final String START_FEED_ELEMENT =
"<feed xmlns=\"http://www.w3.org/2005/Atom\">";
private static final String START_FEED_ELEMENT = "<feed xmlns=\"http://www.w3.org/2005/Atom\">";
/**
* End feed element.
*/
private static final String END_FEED_ELEMENT = "</feed>";
/**
* Start id element.
*/
private static final String START_ID_ELEMENT = "<id>";
/**
* End if element.
*/
private static final String END_ID_ELEMENT = "</id>";
/**
* Start title element.
*/
private static final String START_TITLE_ELEMENT = "<title type=\"text\">";
/**
* End title element.
*/
private static final String END_TITLE_ELEMENT = "</title>";
/**
* Start subtitle element.
*/
private static final String START_SUBTITLE_ELEMENT = "<subtitle type=\"text\"> ";
/**
* End subtitle element.
*/
private static final String END_SUBTITLE_ELEMENT = "</subtitle>";
/**
* Start updated element.
*/
private static final String START_UPDATED_ELEMENT = "<updated>";
/**
* End updated element.
*/
private static final String END_UPDATED_ELEMENT = "</updated>";
/**
* Start author element.
*/
private static final String START_AUTHOR_ELEMENT = "<author>";
/**
* End author element.
*/
private static final String END_AUTHOR_ELEMENT = "</author>";
/**
* Start name element.
*/
private static final String START_NAME_ELEMENT = "<name>";
/**
* End name element.
*/
private static final String END_NAME_ELEMENT = "</name>";
/**
* Link element.
*/
......@@ -259,6 +284,7 @@ public final class Feed {
@Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(START_DOCUMENT);
stringBuilder.append(START_FEED_ELEMENT);
......@@ -276,9 +302,7 @@ public final class Feed {
stringBuilder.append(START_UPDATED_ELEMENT);
stringBuilder.append(DateFormatUtils.format(// using ISO-8601 instead of RFC-3339
updated,
DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(),
TimeZone.getTimeZone(TIME_ZONE_ID)));
updated, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), TimeZone.getTimeZone(TIME_ZONE_ID)));
stringBuilder.append(END_UPDATED_ELEMENT);
stringBuilder.append(START_AUTHOR_ELEMENT);
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.model.feed.rss;
/**
* Category.
*
......@@ -27,8 +28,8 @@ public final class Category {
/**
* Category element.
*/
private static final String CATEGORY_ELEMENT =
"<category>${term}</category>";
private static final String CATEGORY_ELEMENT = "<category>${term}</category>";
/**
* Term.
*/
......
......@@ -15,11 +15,13 @@
*/
package org.b3log.solo.model.feed.rss;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.time.DateFormatUtils;
/**
* RSS 2.0 channel.
*
......@@ -40,104 +42,124 @@ public final class Channel {
* Title.
*/
private String title;
/**
* Link.
*/
private String link;
/**
* Atom link.
*/
private String atomLink;
/**
* Description.
*/
private String description;
/**
* Generator.
*/
private String generator;
/**
* Last build date.
*/
private Date lastBuildDate;
/**
* Language.
*/
private String language;
/**
* Items.
*/
private List<Item> items = new ArrayList<Item>();
/**
* Time zone id.
*/
public static final String TIME_ZONE_ID = "Asia/Shanghai";
/**
* Start.
*/
private static final String START =
"<?xml version='1.0' encoding='UTF-8'?><rss version=\"2.0\" "
private static final String START = "<?xml version='1.0' encoding='UTF-8'?><rss version=\"2.0\" "
+ "xmlns:atom=\"http://www.w3.org/2005/Atom\"><channel>";
/**
* End.
*/
private static final String END = "</channel></rss>";
/**
* Start title element.
*/
private static final String START_TITLE_ELEMENT = "<title>";
/**
* End title element.
*/
private static final String END_TITLE_ELEMENT = "</title>";
/**
* Start link element.
*/
private static final String START_LINK_ELEMENT = "<link>";
/**
* Atom link variable.
*/
private static final String ATOM_LINK_VARIABLE = "${atomLink}";
/**
* End link element.
*/
private static final String END_LINK_ELEMENT = "</link>";
/**
* Atom link element.
*/
private static final String ATOM_LINK_ELEMENT =
"<atom:link href=\""
+ ATOM_LINK_VARIABLE
private static final String ATOM_LINK_ELEMENT = "<atom:link href=\"" + ATOM_LINK_VARIABLE
+ "\" rel=\"self\" type=\"application/rss+xml\" />";
/**
* Start description element.
*/
private static final String START_DESCRIPTION_ELEMENT = "<description>";
/**
* End description element.
*/
private static final String END_DESCRIPTION_ELEMENT = "</description>";
/**
* Start generator element.
*/
private static final String START_GENERATOR_ELEMENT = "<generator>";
/**
* End generator element.
*/
private static final String END_GENERATOR_ELEMENT = "</generator>";
/**
* Start language element.
*/
private static final String START_LANGUAGE_ELEMENT = "<language>";
/**
* End language element.
*/
private static final String END_LANGUAGE_ELEMENT = "</language>";
/**
* Start last build date element.
*/
private static final String START_LAST_BUILD_DATE_ELEMENT =
"<lastBuildDate>";
private static final String START_LAST_BUILD_DATE_ELEMENT = "<lastBuildDate>";
/**
* End last build date element.
*/
......@@ -281,6 +303,7 @@ public final class Channel {
@Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(START);
stringBuilder.append(START_TITLE_ELEMENT);
......@@ -291,8 +314,7 @@ public final class Channel {
stringBuilder.append(link);
stringBuilder.append(END_LINK_ELEMENT);
stringBuilder.append(ATOM_LINK_ELEMENT.replace(ATOM_LINK_VARIABLE,
atomLink));
stringBuilder.append(ATOM_LINK_ELEMENT.replace(ATOM_LINK_VARIABLE, atomLink));
stringBuilder.append(START_DESCRIPTION_ELEMENT);
stringBuilder.append(description);
......@@ -303,8 +325,7 @@ public final class Channel {
stringBuilder.append(END_GENERATOR_ELEMENT);
stringBuilder.append(START_LAST_BUILD_DATE_ELEMENT);
stringBuilder.append(DateFormatUtils.SMTP_DATETIME_FORMAT.format(
lastBuildDate));
stringBuilder.append(DateFormatUtils.SMTP_DATETIME_FORMAT.format(lastBuildDate));
stringBuilder.append(END_LAST_BUILD_DATE_ELEMENT);
stringBuilder.append(START_LANGUAGE_ELEMENT);
......
......@@ -15,12 +15,14 @@
*/
package org.b3log.solo.model.feed.rss;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import org.apache.commons.lang.time.DateFormatUtils;
/**
* Item.
*
......@@ -33,86 +35,93 @@ public final class Item {
/**
* Start title element.
*/
private static final String START_TITLE_ELEMENT =
"<title>";
private static final String START_TITLE_ELEMENT = "<title>";
/**
* End title element.
*/
private static final String END_TITLE_ELEMENT =
"</title>";
private static final String END_TITLE_ELEMENT = "</title>";
/**
* Start link element.
*/
private static final String START_LINK_ELEMENT =
"<link>";
private static final String START_LINK_ELEMENT = "<link>";
/**
* End link element.
*/
private static final String END_LINK_ELEMENT = "</link>";
/**
* Start description element.
*/
private static final String START_DESCRIPTION_ELEMENT =
"<description>";
private static final String START_DESCRIPTION_ELEMENT = "<description>";
/**
* End summary element.
*/
private static final String END_DESCRIPTION_ELEMENT =
"</description>";
private static final String END_DESCRIPTION_ELEMENT = "</description>";
/**
* Start author element.
*/
private static final String START_AUTHOR_ELEMENT =
"<author>";
private static final String START_AUTHOR_ELEMENT = "<author>";
/**
* End author element.
*/
private static final String END_AUTHOR_ELEMENT =
"</author>";
private static final String END_AUTHOR_ELEMENT = "</author>";
/**
* Categories.
*/
private Set<Category> categories = new HashSet<Category>();
/**
* Start guid element.
*/
private static final String START_GUID_ELEMENT =
"<guid>";
private static final String START_GUID_ELEMENT = "<guid>";
/**
* End guid element.
*/
private static final String END_GUID_ELEMENT =
"</guid>";
private static final String END_GUID_ELEMENT = "</guid>";
/**
* Start pubDate element.
*/
private static final String START_PUB_DATE_ELEMENT =
"<pubDate>";
private static final String START_PUB_DATE_ELEMENT = "<pubDate>";
/**
* End pubDate element.
*/
private static final String END_PUB_DATE_ELEMENT =
"</pubDate>";
private static final String END_PUB_DATE_ELEMENT = "</pubDate>";
/**
* Guid.
*/
private String guid;
/**
* Publish date.
*/
private Date pubDate;
/**
* Title.
*/
private String title;
/**
* Description.
*/
private String description;
/**
* Link.
*/
private String link;
/**
* Author.
*/
......@@ -264,9 +273,7 @@ public final class Item {
}
stringBuilder.append(START_PUB_DATE_ELEMENT);
stringBuilder.append(DateFormatUtils.format(
pubDate, "EEE, dd MMM yyyy HH:mm:ss z",
TimeZone.getTimeZone(Channel.TIME_ZONE_ID)));
stringBuilder.append(DateFormatUtils.format(pubDate, "EEE, dd MMM yyyy HH:mm:ss z", TimeZone.getTimeZone(Channel.TIME_ZONE_ID)));
stringBuilder.append(END_PUB_DATE_ELEMENT).append("</item>");
return stringBuilder.toString();
......
......@@ -15,9 +15,11 @@
*/
package org.b3log.solo.model.sitemap;
import java.util.ArrayList;
import java.util.List;
/**
* Sitemap.
*
......@@ -36,17 +38,18 @@ public final class Sitemap {
/**
* Start document.
*/
private static final String START_DOCUMENT =
"<?xml version='1.0' encoding='UTF-8'?>";
private static final String START_DOCUMENT = "<?xml version='1.0' encoding='UTF-8'?>";
/**
* Start URL set element.
*/
private static final String START_URL_SET_ELEMENT =
"<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">";
private static final String START_URL_SET_ELEMENT = "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">";
/**
* End URL set element.
*/
private static final String END_URL_SET_ELEMENT = "</urlset>";
/**
* URLs.
*/
......@@ -64,6 +67,7 @@ public final class Sitemap {
@Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(START_DOCUMENT);
stringBuilder.append(START_URL_SET_ELEMENT);
......
......@@ -15,8 +15,10 @@
*/
package org.b3log.solo.model.sitemap;
import org.b3log.latke.util.Strings;
/**
* Sitemap URL.
*
......@@ -30,30 +32,37 @@ public final class URL {
* Start URL element.
*/
private static final String START_URL_ELEMENT = "<url>";
/**
* End URL element.
*/
private static final String END_URL_ELEMENT = "</url>";
/**
* Start loc element.
*/
private static final String START_LOC_ELEMENT = "<loc>";
/**
* End loc element.
*/
private static final String END_LOC_ELEMENT = "</loc>";
/**
* Start last mod element.
*/
private static final String START_LAST_MOD_ELEMENT = "<lastmod>";
/**
* End last mod element.
*/
private static final String END_LAST_MOD_ELEMENT = "</lastmod>";
/**
* Loc.
*/
private String loc;
/**
* Last mod.
*/
......@@ -98,6 +107,7 @@ public final class URL {
@Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(START_URL_ELEMENT);
stringBuilder.append(START_LOC_ELEMENT);
......
......@@ -15,8 +15,10 @@
*/
package org.b3log.solo.plugin.cache;
import org.b3log.latke.plugin.AbstractPlugin;
/**
* Admin cache plugin.
*
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.plugin.cache;
import org.b3log.solo.model.Common;
import java.util.ArrayList;
import java.util.List;
......@@ -41,6 +42,7 @@ import org.b3log.solo.service.PreferenceQueryService;
import org.b3log.solo.util.QueryResults;
import org.json.JSONObject;
/**
* Admin cache service.
*
......@@ -55,14 +57,17 @@ public final class AdminCacheService {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(AdminCacheService.class.getName());
/**
* User utilities.
*/
private Users userUtils = Users.getInstance();
/**
* Preference query service.
*/
private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance();
/**
* Preference management service.
*/
......@@ -96,17 +101,20 @@ public final class AdminCacheService {
}
final JSONRenderer renderer = new JSONRenderer();
context.setRenderer(renderer);
final JSONObject ret = new JSONObject();
renderer.setJSONObject(ret);
LOGGER.log(Level.INFO, "Cache status[cachedBytes={0}, cachedCount={1}]",
new Object[]{PageCaches.getCache().getCachedBytes(), PageCaches.getCache().getCachedCount()});
new Object[] {PageCaches.getCache().getCachedBytes(), PageCaches.getCache().getCachedCount()});
try {
final JSONObject preference = preferenceQueryService.getPreference();
final boolean pageCacheEnabled = preference.getBoolean(Preference.PAGE_CACHE_ENABLED);
ret.put(Preference.PAGE_CACHE_ENABLED, pageCacheEnabled);
ret.put(Common.PAGE_CACHED_CNT, PageCaches.getKeys().size());
......@@ -117,6 +125,7 @@ public final class AdminCacheService {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
final JSONObject jsonObject = QueryResults.defaultResult();
renderer.setJSONObject(jsonObject);
jsonObject.put(Keys.MSG, "Admin Cache plugin exception: " + e.getMessage());
}
......@@ -154,7 +163,7 @@ public final class AdminCacheService {
* @param context the specified http request context
* @throws Exception exception
*/
@RequestProcessing(value = "/console/plugins/admin-cache/pages/" + Requests.PAGINATION_PATH_PATTERN,
@RequestProcessing(value = "/console/plugins/admin-cache/pages/*/*/*"/* Requests.PAGINATION_PATH_PATTERN */,
method = HTTPRequestMethod.GET)
public void getPages(final HttpServletRequest request, final HttpServletResponse response, final HTTPRequestContext context)
throws Exception {
......@@ -164,9 +173,11 @@ public final class AdminCacheService {
}
final JSONRenderer renderer = new JSONRenderer();
context.setRenderer(renderer);
final JSONObject ret = new JSONObject();
renderer.setJSONObject(ret);
try {
......@@ -181,22 +192,25 @@ public final class AdminCacheService {
List<String> keys = new ArrayList<String>(PageCaches.getKeys());
// Paginates
final int pageCount =
(int) Math.ceil((double) keys.size() / (double) pageSize);
final int pageCount = (int) Math.ceil((double) keys.size() / (double) pageSize);
final JSONObject pagination = new JSONObject();
ret.put(Pagination.PAGINATION, pagination);
final List<Integer> pageNums = Paginator.paginate(currentPageNum, pageSize, pageCount, windowSize);
pagination.put(Pagination.PAGINATION_PAGE_COUNT, pageCount);
pagination.put(Pagination.PAGINATION_PAGE_NUMS, pageNums);
final int start = pageSize * (currentPageNum - 1);
int end = start + pageSize;
end = end > keys.size() ? keys.size() : end;
keys = keys.subList(start, end);
// Retrives cached pages
final List<JSONObject> pages = new ArrayList<JSONObject>();
for (final String key : keys) {
LOGGER.log(Level.FINER, "Cached page[key={0}]", key);
......@@ -204,8 +218,7 @@ public final class AdminCacheService {
if (null != cachedPage) {
// Do a copy for properties removing and retrieving
cachedPage = new JSONObject(cachedPage,
JSONObject.getNames(cachedPage));
cachedPage = new JSONObject(cachedPage, JSONObject.getNames(cachedPage));
cachedPage.remove(PageCaches.CACHED_CONTENT);
pages.add(cachedPage);
}
......@@ -218,6 +231,7 @@ public final class AdminCacheService {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
final JSONObject jsonObject = QueryResults.defaultResult();
renderer.setJSONObject(jsonObject);
jsonObject.put(Keys.MSG, "Admin Cache plugin exception: " + e.getMessage());
}
......@@ -251,9 +265,11 @@ public final class AdminCacheService {
}
final JSONRenderer renderer = new JSONRenderer();
context.setRenderer(renderer);
final JSONObject ret = new JSONObject();
renderer.setJSONObject(ret);
try {
......@@ -263,6 +279,7 @@ public final class AdminCacheService {
final boolean pageCacheEnabled = "true".equals(path) ? true : false;
final JSONObject preference = preferenceQueryService.getPreference();
preference.put(Preference.PAGE_CACHE_ENABLED, pageCacheEnabled);
preferenceMgmtService.updatePreference(preference);
......@@ -272,6 +289,7 @@ public final class AdminCacheService {
LOGGER.log(Level.SEVERE, "Sets page cache error: {0}", e.getMessage());
final JSONObject jsonObject = QueryResults.defaultResult();
renderer.setJSONObject(jsonObject);
jsonObject.put(Keys.MSG, "Admin Cache plugin exception: " + e.getMessage());
}
......
......@@ -15,8 +15,10 @@
*/
package org.b3log.solo.plugin.fancybox;
import org.b3log.latke.plugin.AbstractPlugin;
/**
* Shows images with <a href="http://fancybox.net/howto">jQuery Fancy</a>.
*
......
......@@ -15,8 +15,10 @@
*/
package org.b3log.solo.plugin.symphony;
import org.b3log.latke.plugin.AbstractPlugin;
/**
* Getting news from <a href="http://symphony.b3log.org">B3log Symphony</a>.
*
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.processor;
import org.b3log.latke.Latkes;
import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestMethod;
......@@ -28,6 +29,7 @@ import org.b3log.solo.service.TagQueryService;
import org.b3log.solo.util.Articles;
import org.json.JSONObject;
/**
* Blog processor.
*
......@@ -42,10 +44,12 @@ public final class BlogProcessor {
* Article utilities.
*/
private Articles articleUtils = Articles.getInstance();
/**
* Tag query service.
*/
private TagQueryService tagQueryService = TagQueryService.getInstance();
/**
* Statistic query service.
*/
......@@ -72,13 +76,16 @@ public final class BlogProcessor {
@RequestProcessing(value = "/blog/info", method = HTTPRequestMethod.GET)
public void getRecentArticleTime(final HTTPRequestContext context) throws Exception {
final JSONRenderer renderer = new JSONRenderer();
context.setRenderer(renderer);
final JSONObject jsonObject = new JSONObject();
renderer.setJSONObject(jsonObject);
jsonObject.put("recentArticleTime", articleUtils.getRecentArticleTime());
final JSONObject statistic = statisticQueryService.getStatistic();
jsonObject.put("articleCount", statistic.getLong(Statistic.STATISTIC_PUBLISHED_ARTICLE_COUNT));
jsonObject.put("commentCount", statistic.getLong(Statistic.STATISTIC_PUBLISHED_BLOG_COMMENT_COUNT));
jsonObject.put("tagCount", tagQueryService.getTagCount());
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.processor;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -32,6 +33,7 @@ import org.b3log.solo.model.Common;
import org.b3log.solo.util.Users;
import org.json.JSONObject;
/**
* Cache processor.
*
......@@ -46,6 +48,7 @@ public final class CacheProcessor {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(CacheProcessor.class.getName());
/**
* User utilities.
*/
......@@ -75,6 +78,7 @@ public final class CacheProcessor {
if (Strings.isEmptyOrNull(all)) { // Just clears single page cache
final String uri = requestJSONObject.optString(Common.URI);
clearPageCache(uri);
} else { // Clears all page caches
clearAllPageCache();
......@@ -93,6 +97,7 @@ public final class CacheProcessor {
*/
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);
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.processor;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
......@@ -43,6 +44,7 @@ import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.PNGRenderer;
import org.b3log.solo.SoloServletListener;
/**
* Captcha processor.
*
......@@ -62,18 +64,22 @@ public final class CaptchaProcessor {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(CaptchaProcessor.class.getName());
/**
* Images service.
*/
private static final ImageService IMAGE_SERVICE = ImageServiceFactory.getImageService();
/**
* Key of captcha.
*/
public static final String CAPTCHA = "captcha";
/**
* Captchas.
*/
private Image[] captchas;
/**
* Count of static captchas.
*/
......@@ -87,6 +93,7 @@ public final class CaptchaProcessor {
@RequestProcessing(value = "/captcha.do", method = HTTPRequestMethod.GET)
public void get(final HTTPRequestContext context) {
final PNGRenderer renderer = new PNGRenderer();
context.setRenderer(renderer);
if (null == captchas) {
......@@ -103,8 +110,9 @@ public final class CaptchaProcessor {
final String captcha = captchaImg.getName();
final HttpSession httpSession = request.getSession(false);
if (null != httpSession) {
LOGGER.log(Level.FINER, "Captcha[{0}] for session[id={1}]", new Object[]{captcha, httpSession.getId()});
LOGGER.log(Level.FINER, "Captcha[{0}] for session[id={1}]", new Object[] {captcha, httpSession.getId()});
httpSession.setAttribute(CAPTCHA, captcha);
}
......@@ -128,10 +136,12 @@ public final class CaptchaProcessor {
captchas = new Image[CAPTCHA_COUNT];
ZipFile zipFile;
if (RuntimeEnv.LOCAL == Latkes.getRuntimeEnv()) {
final InputStream inputStream = SoloServletListener.class.getClassLoader().getResourceAsStream("captcha_static.zip");
final File file = File.createTempFile("b3log_captcha_static", null);
final OutputStream outputStream = new FileOutputStream(file);
IOUtils.copy(inputStream, outputStream);
zipFile = new ZipFile(file);
......@@ -139,21 +149,25 @@ public final class CaptchaProcessor {
IOUtils.closeQuietly(outputStream);
} else {
final URL captchaURL = SoloServletListener.class.getClassLoader().getResource("captcha_static.zip");
zipFile = new ZipFile(captchaURL.getFile());
}
final Enumeration<? extends ZipEntry> entries = zipFile.entries();
int i = 0;
while (entries.hasMoreElements()) {
final ZipEntry entry = entries.nextElement();
final BufferedInputStream bufferedInputStream = new BufferedInputStream(zipFile.getInputStream(entry));
final byte[] captchaCharData = new byte[bufferedInputStream.available()];
bufferedInputStream.read(captchaCharData);
bufferedInputStream.close();
final Image image = IMAGE_SERVICE.makeImage(captchaCharData);
image.setName(entry.getName().substring(0, entry.getName().lastIndexOf('.')));
captchas[i] = image;
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.processor;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -38,6 +39,7 @@ import org.b3log.solo.util.Comments;
import org.b3log.solo.util.Users;
import org.json.JSONObject;
/**
* Comment processor.
*
......@@ -52,10 +54,12 @@ public final class CommentProcessor {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(CommentProcessor.class.getName());
/**
* Language service.
*/
private static LangPropsService langPropsService = LangPropsService.getInstance();
/**
* Comment management service.
*/
......@@ -100,11 +104,13 @@ public final class CommentProcessor {
final HttpServletResponse httpServletResponse = context.getResponse();
final JSONObject requestJSONObject = Requests.parseRequestJSONObject(httpServletRequest, httpServletResponse);
requestJSONObject.put(Common.TYPE, Page.PAGE);
final JSONObject jsonObject = Comments.checkAddCommentRequest(requestJSONObject);
final JSONRenderer renderer = new JSONRenderer();
context.setRenderer(renderer);
renderer.setJSONObject(jsonObject);
......@@ -114,6 +120,7 @@ public final class CommentProcessor {
}
final HttpSession session = httpServletRequest.getSession(false);
if (null == session) {
jsonObject.put(Keys.STATUS_CODE, false);
jsonObject.put(Keys.MSG, langPropsService.get("captchaErrorLabel"));
......@@ -124,6 +131,7 @@ public final class CommentProcessor {
if (!Users.getInstance().isLoggedIn(httpServletRequest, httpServletResponse)) {
final String storedCaptcha = (String) session.getAttribute(CaptchaProcessor.CAPTCHA);
final String captcha = requestJSONObject.optString(CaptchaProcessor.CAPTCHA);
if (null == storedCaptcha || !storedCaptcha.equals(captcha)) {
jsonObject.put(Keys.STATUS_CODE, false);
jsonObject.put(Keys.MSG, langPropsService.get("captchaErrorLabel"));
......@@ -136,6 +144,7 @@ public final class CommentProcessor {
try {
final JSONObject addResult = commentMgmtService.addPageComment(requestJSONObject);
addResult.put(Keys.STATUS_CODE, true);
renderer.setJSONObject(addResult);
......@@ -180,17 +189,19 @@ public final class CommentProcessor {
* @throws ServletException servlet 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 {
final HttpServletRequest httpServletRequest = context.getRequest();
final HttpServletResponse httpServletResponse = context.getResponse();
final JSONObject requestJSONObject = Requests.parseRequestJSONObject(httpServletRequest, httpServletResponse);
requestJSONObject.put(Common.TYPE, Article.ARTICLE);
final JSONObject jsonObject = Comments.checkAddCommentRequest(requestJSONObject);
final JSONRenderer renderer = new JSONRenderer();
context.setRenderer(renderer);
renderer.setJSONObject(jsonObject);
......@@ -200,6 +211,7 @@ public final class CommentProcessor {
}
final HttpSession session = httpServletRequest.getSession(false);
if (null == session) {
jsonObject.put(Keys.STATUS_CODE, false);
jsonObject.put(Keys.MSG, langPropsService.get("captchaErrorLabel"));
......@@ -210,6 +222,7 @@ public final class CommentProcessor {
if (!Users.getInstance().isLoggedIn(httpServletRequest, httpServletResponse)) {
final String storedCaptcha = (String) session.getAttribute(CaptchaProcessor.CAPTCHA);
final String captcha = requestJSONObject.optString(CaptchaProcessor.CAPTCHA);
if (null == storedCaptcha || !storedCaptcha.equals(captcha)) {
jsonObject.put(Keys.STATUS_CODE, false);
jsonObject.put(Keys.MSG, langPropsService.get("captchaErrorLabel"));
......
......@@ -15,6 +15,7 @@
*/
package org.b3log.solo.processor;
import java.io.File;
import java.io.IOException;
import java.util.Map;
......@@ -37,6 +38,7 @@ import org.b3log.solo.processor.util.Filler;
import org.b3log.solo.service.PreferenceQueryService;
import org.json.JSONObject;
/**
* Error processor.
*
......@@ -51,18 +53,22 @@ public final class ErrorProcessor {
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(ArticleProcessor.class.getName());
/**
* Filler.
*/
private Filler filler = Filler.getInstance();
/**
* Preference query service.
*/
private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance();
/**
* Language service.
*/
private LangPropsService langPropsService = LangPropsService.getInstance();
/**
* User service.
*/
......@@ -81,10 +87,12 @@ public final class ErrorProcessor {
throws IOException {
final String requestURI = request.getRequestURI();
String templateName = StringUtils.substringAfterLast(requestURI, "/");
templateName = StringUtils.substringBefore(templateName, ".") + ".ftl";
LOGGER.log(Level.FINE, "Shows error page[requestURI={0}, templateName={1}]", new Object[]{requestURI, templateName});
LOGGER.log(Level.FINE, "Shows error page[requestURI={0}, templateName={1}]", new Object[] {requestURI, templateName});
final ConsoleRenderer renderer = new ConsoleRenderer();
context.setRenderer(renderer);
renderer.setTemplateName("error" + File.separatorChar + templateName);
......@@ -92,6 +100,7 @@ public final class ErrorProcessor {
try {
final Map<String, String> langs = langPropsService.getAll(Locales.getLocale(request));
dataModel.putAll(langs);
final JSONObject preference = preferenceQueryService.getPreference();
......
......@@ -15,10 +15,12 @@
*/
package org.b3log.solo.repository;
import org.b3log.latke.repository.Repository;
import org.b3log.latke.repository.RepositoryException;
import org.json.JSONObject;
/**
* Archive date-Article repository.
*
......
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