Commit a7d7d7ad authored by Vanessa's avatar Vanessa

Signed-off-by: Vanessa <lly219@gmail.com>

parent f58c2c1e
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<project-shared-configuration>
<!--
This file contains additional configuration written by modules in the NetBeans IDE.
The configuration is intended to be shared among all the users of project and
therefore it is assumed to be part of version control checkout.
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
-->
<spellchecker-wordlist xmlns="http://www.netbeans.org/ns/spellchecker-wordlist/1">
<word>Admin</word>
<word>app</word>
<word>blog</word>
<word>blogger</word>
<word>blogging</word>
<word>captcha</word>
<word>Captcha</word>
<word>cron</word>
<word>datastore</word>
<word>ftl</word>
<word>Gmail</word>
<word>http</word>
<word>json</word>
<word>Latke</word>
<word>loc</word>
<word>memcache</word>
<word>permalink</word>
<word>permalinks</word>
<word>Picasa</word>
<word>Plugin</word>
<word>plugin</word>
<word>Pluginable</word>
<word>Plugins</word>
<word>plugins</word>
<word>servlet</word>
<word>servlets</word>
<word>sitemap</word>
<word>struct</word>
<word>structs</word>
<word>Upgrader</word>
<word>Upgraders</word>
</spellchecker-wordlist>
</project-shared-configuration>
<?xml version="1.0" encoding="UTF-8"?>
<actions>
<action>
<actionName>CUSTOM-cobertura-cobertura</actionName>
<displayName>cobertura-cobertura</displayName>
<goals>
<goal>cobertura:cobertura</goal>
</goals>
</action>
</actions>
<?xml version="1.0" encoding="UTF-8"?>
<!--
Description: B3log Solo core.
Version: 2.0.0.8, May 11, 2012
Author: Liang Ding
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.b3log</groupId>
<artifactId>solo-core</artifactId>
<packaging>jar</packaging>
<name>B3log Solo (Core)</name>
<description>B3log Solo Core.</description>
<parent>
<groupId>org.b3log</groupId>
<artifactId>solo</artifactId>
<version>0.4.5</version>
</parent>
<dependencies>
<dependency>
<groupId>org.b3log</groupId>
<artifactId>latke</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
</dependency>
<!-- BEGIN GAE related dependencies just for test -->
<dependency>
<groupId>org.b3log</groupId>
<artifactId>latke-gae</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-labs</artifactId>
<version>${gae.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-stubs</artifactId>
<version>${gae.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-testing</artifactId>
<version>${gae.version}</version>
<scope>test</scope>
</dependency>
<!-- END GAE related dependencies just for test -->
<dependency>
<groupId>org.tautua.markdownpapers</groupId>
<artifactId>markdownpapers-core</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>etc/</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<skipTests>false</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>com.mycila.maven-license-plugin</groupId>
<artifactId>maven-license-plugin</artifactId>
<configuration>
<header>../src/main/resources/etc/header.txt</header>
</configuration>
</plugin>
<!-- For source code style check -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${maven-checkstyle-plugin.version}</version>
<inherited>false</inherited>
<configuration>
<configLocation>src/main/resources/etc/beyondtrack_checks.xml</configLocation>
<includeTestSourceDirectory>false</includeTestSourceDirectory>
<excludes>
com/**/*.java,
</excludes>
<consoleOutput>true</consoleOutput>
<failOnViolation>true</failOnViolation>
<failsOnError>true</failsOnError>
<encoding>UTF-8</encoding>
<!-- Do NOT skip code style check before committing -->
<skip>false</skip>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>checkstyle</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<configuration>
<show>private</show>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>${maven-cobertura-plugin.version}</version>
</plugin>
</plugins>
</build>
</project>
This diff is collapsed.
/**
* Admin index.ftl template and upload/download processing, .
*/
package org.b3log.solo.action;
/**
* <a href="http://www.xmlrpc.com/metaWeblogApi">MetaWeblog API</a> requests
* processing.
*/
package org.b3log.solo.api.metaweblog;
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.dev;
import java.io.IOException;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.b3log.latke.Latkes;
import org.b3log.latke.RuntimeMode;
import org.b3log.latke.annotation.RequestProcessing;
import org.b3log.latke.annotation.RequestProcessor;
import org.b3log.latke.model.User;
import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.util.Stopwatchs;
import org.b3log.solo.model.Article;
import org.b3log.solo.service.ArticleMgmtService;
import org.b3log.solo.service.UserQueryService;
import org.json.JSONObject;
/**
* Generates some dummy articles for development testing.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.3, May 21, 2012
* @since 0.4.0
*/
@RequestProcessor
public final class ArticleGenerator {
/**
* Logger.
*/
private static final Logger LOGGER =
Logger.getLogger(ArticleGenerator.class.getName());
/**
* Generates some dummy articles with the specified context.
*
* @param context the specified context
* @param request the specified request
* @param response the specified response
* @throws IOException io exception
*/
@RequestProcessing(value = "/dev/articles/gen/*", method = HTTPRequestMethod.GET)
public void genArticles(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response)
throws IOException {
if (RuntimeMode.DEVELOPMENT != Latkes.getRuntimeMode()) {
LOGGER.log(Level.WARNING, "Article generation just for development mode, " + "current runtime mode is [{0}]",
Latkes.getRuntimeMode());
response.sendRedirect("/");
return;
}
Stopwatchs.start("Gen Articles");
final String requestURI = request.getRequestURI();
final int num = Integer.valueOf(requestURI.substring((Latkes.getContextPath() + "/dev/articles/gen/").length()));
try {
final ArticleMgmtService articleMgmtService = ArticleMgmtService.getInstance();
final UserQueryService userQueryService = UserQueryService.getInstance();
final JSONObject admin = userQueryService.getAdmin();
final String authorEmail = admin.optString(User.USER_EMAIL);
for (int i = 0; i < num; i++) {
final JSONObject article = new JSONObject();
// XXX: http://en.wikipedia.org/wiki/Markov_chain
article.put(Article.ARTICLE_TITLE, "article title" + i);
article.put(Article.ARTICLE_ABSTRACT, "article" + i + " abstract");
article.put(Article.ARTICLE_TAGS_REF, "tag1,tag2");
article.put(Article.ARTICLE_AUTHOR_EMAIL, authorEmail);
article.put(Article.ARTICLE_COMMENT_COUNT, 0);
article.put(Article.ARTICLE_VIEW_COUNT, 0);
article.put(Article.ARTICLE_CONTENT, "article content");
article.put(Article.ARTICLE_PERMALINK, "article" + i + " permalink");
article.put(Article.ARTICLE_HAD_BEEN_PUBLISHED, true);
article.put(Article.ARTICLE_IS_PUBLISHED, true);
article.put(Article.ARTICLE_PUT_TOP, false);
article.put(Article.ARTICLE_CREATE_DATE, new Date());
article.put(Article.ARTICLE_UPDATE_DATE, new Date());
article.put(Article.ARTICLE_RANDOM_DOUBLE, Math.random());
article.put(Article.ARTICLE_COMMENTABLE, true);
article.put(Article.ARTICLE_VIEW_PWD, "");
article.put(Article.ARTICLE_SIGN_ID, "1");
articleMgmtService.addArticle(new JSONObject().put(Article.ARTICLE, article));
}
} catch (final Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
}
Stopwatchs.end();
response.sendRedirect("/");
}
}
/**
* Development usage.
*
* <p>
* All functions in this package just for development mode.
* </p>
*/
package org.b3log.solo.dev;
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.event;
/**
* Event types.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.6, Oct 19, 2011
* @since 0.3.1
*/
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 to page event.
*/
public static final String ADD_COMMENT_TO_PAGE = "Add Comment To Page";
/**
* Indicates a remove comment event.
*/
public static final String REMOVE_COMMENT = "Remove Comment";
/**
* Private default constructor.
*/
private EventTypes() {
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.event.comment;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.b3log.latke.Keys;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.mail.MailService;
import org.b3log.latke.mail.MailService.Message;
import org.b3log.latke.mail.MailServiceFactory;
import org.b3log.latke.util.Strings;
import org.b3log.solo.SoloServletListener;
import org.b3log.solo.event.EventTypes;
import org.b3log.solo.model.Comment;
import org.b3log.solo.model.Preference;
import org.b3log.solo.repository.CommentRepository;
import org.b3log.solo.model.Article;
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.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.1.4, Oct 31, 2011
* @since 0.3.1
*/
public final class ArticleCommentReplyNotifier
extends AbstractEventListener<JSONObject> {
/**
* 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.
*/
private PreferenceQueryService preferenceQueryService =
PreferenceQueryService.getInstance();
@Override
public void action(final Event<JSONObject> event) throws EventException {
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()});
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;
}
try {
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");
}
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 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);
final String articleLink = "http://" + blogHost + article.getString(
Article.ARTICLE_PERMALINK);
final String commentName = comment.getString(Comment.COMMENT_NAME);
final String commentURL = comment.getString(Comment.COMMENT_URL);
String commenter = null;
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);
message.setHtmlBody(mailBody);
LOGGER.log(Level.FINER,
"Sending a mail[mailSubject={0}, mailBody=[{1}] to [{2}]",
new Object[]{mailSubject, mailBody,
originalCommentEmail});
mailService.send(message);
} catch (final Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new EventException("Reply notifier error!");
}
}
/**
* Gets the event type {@linkplain EventTypes#ADD_COMMENT_TO_ARTICLE}.
*
* @return event type
*/
@Override
public String getEventType() {
return EventTypes.ADD_COMMENT_TO_ARTICLE;
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.event.comment;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.b3log.latke.Keys;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.mail.MailService;
import org.b3log.latke.mail.MailService.Message;
import org.b3log.latke.mail.MailServiceFactory;
import org.b3log.latke.util.Strings;
import org.b3log.solo.SoloServletListener;
import org.b3log.solo.event.EventTypes;
import org.b3log.solo.model.Comment;
import org.b3log.solo.model.Preference;
import org.b3log.solo.repository.CommentRepository;
import org.b3log.solo.model.Page;
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.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.1.1, Oct 31, 2011
* @since 0.3.1
*/
public final class PageCommentReplyNotifier
extends AbstractEventListener<JSONObject> {
/**
* 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.
*/
private PreferenceQueryService preferenceQueryService =
PreferenceQueryService.getInstance();
@Override
public void action(final Event<JSONObject> event) throws EventException {
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()});
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;
}
try {
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");
}
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 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);
final String pageLink = "http://" + blogHost
+ page.getString(Page.PAGE_PERMALINK);
final String commentName = comment.getString(Comment.COMMENT_NAME);
final String commentURL = comment.getString(Comment.COMMENT_URL);
String commenter = null;
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);
message.setHtmlBody(mailBody);
LOGGER.log(Level.FINER,
"Sending a mail[mailSubject={0}, mailBody=[{1}] to [{2}]",
new Object[]{mailSubject, mailBody,
originalCommentEmail});
mailService.send(message);
} catch (final Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new EventException("Reply notifier error!");
}
}
/**
* Gets the event type {@linkplain EventTypes#ADD_COMMENT_TO_PAGE}.
*
* @return event type
*/
@Override
public String getEventType() {
return EventTypes.ADD_COMMENT_TO_PAGE;
}
}
/**
* Event processors.
*/
package org.b3log.solo.event;
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.event.ping;
import java.net.URL;
import java.net.URLEncoder;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang.StringUtils;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.urlfetch.HTTPRequest;
import org.b3log.latke.urlfetch.URLFetchService;
import org.b3log.latke.urlfetch.URLFetchServiceFactory;
import org.b3log.solo.event.EventTypes;
import org.b3log.solo.model.Article;
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.
*
* <p>
* <li>
* <a href="http://www.google.com/help/blogsearch/pinging_API.html">
* About Google Blog Search Pinging Service API</a>
* </li>
* </p>
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.2, Jun 23, 2011
* @see UpdateArticleGoogleBlogSearchPinger
* @since 0.3.1
*/
public final class AddArticleGoogleBlogSearchPinger extends AbstractEventListener<JSONObject> {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(AddArticleGoogleBlogSearchPinger.class.getName());
/**
* URL fetch service.
*/
private static final URLFetchService URL_FETCH_SERVICE = URLFetchServiceFactory.getURLFetchService();
/**
* Gets the event type {@linkplain EventTypes#ADD_ARTICLE}.
*
* @return event type
*/
@Override
public String getEventType() {
return EventTypes.ADD_ARTICLE;
}
@Override
public void action(final Event<JSONObject> event) throws EventException {
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)});
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 HTTPRequest request = new HTTPRequest();
request.setURL(new URL(spec));
URL_FETCH_SERVICE.fetchAsync(request);
} catch (final Exception e) {
LOGGER.log(Level.SEVERE, "Ping Google Blog Search Service fail while adding an article[title=" + articleTitle + "]", e);
}
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.event.ping;
import java.net.URL;
import java.net.URLEncoder;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang.StringUtils;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.urlfetch.HTTPRequest;
import org.b3log.latke.urlfetch.URLFetchService;
import org.b3log.latke.urlfetch.URLFetchServiceFactory;
import org.b3log.solo.event.EventTypes;
import org.b3log.solo.model.Article;
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.
*
* <p>
* <li>
* <a href="http://www.google.com/help/blogsearch/pinging_API.html">
* About Google Blog Search Pinging Service API</a>
* </li>
* </p>
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.2, Jun 23, 2011
* @see AddArticleGoogleBlogSearchPinger
* @since 0.3.1
*/
public final class UpdateArticleGoogleBlogSearchPinger
extends AbstractEventListener<JSONObject> {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(UpdateArticleGoogleBlogSearchPinger.class.getName());
/**
* URL fetch service.
*/
private static final URLFetchService URL_FETCH_SERVICE = URLFetchServiceFactory.getURLFetchService();
/**
* Gets the event type {@linkplain EventTypes#UPDATE_ARTICLE}.
*
* @return event type
*/
@Override
public String getEventType() {
return EventTypes.UPDATE_ARTICLE;
}
@Override
public void action(final Event<JSONObject> event) throws EventException {
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)});
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 HTTPRequest request = new HTTPRequest();
request.setURL(new URL(spec));
URL_FETCH_SERVICE.fetchAsync(request);
} catch (final Exception e) {
LOGGER.log(Level.SEVERE, "Ping Google Blog Search Service fail while updating an " + "article[title=" + articleTitle + "]", e);
}
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.event.plugin;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.plugin.AbstractPlugin;
import org.b3log.latke.plugin.PluginManager;
import org.b3log.latke.repository.Transaction;
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.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.1, Nov 28, 2011
* @since 0.3.1
*/
public final class PluginRefresher extends AbstractEventListener<List<AbstractPlugin>> {
/**
* Logger.
*/
private static final Logger LOGGER =
Logger.getLogger(PluginRefresher.class.getName());
/**
* Plugin repository.
*/
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()});
final Transaction transaction = pluginRepository.beginTransaction();
transaction.clearQueryCache(false);
try {
Plugins.refresh(plugins);
transaction.commit();
} catch (final Exception e) {
if (transaction.isActive()) {
transaction.rollback();
}
LOGGER.log(Level.SEVERE, "Processing plugin loaded event error", e);
throw new EventException(e);
}
}
/**
* Gets the event type {@linkplain PluginManager#PLUGIN_LOADED_EVENT}.
*
* @return event type
*/
@Override
public String getEventType() {
return PluginManager.PLUGIN_LOADED_EVENT;
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.event.rhythm;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.b3log.latke.Keys;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.urlfetch.HTTPRequest;
import org.b3log.latke.urlfetch.URLFetchService;
import org.b3log.latke.urlfetch.URLFetchServiceFactory;
import org.b3log.solo.SoloServletListener;
import org.b3log.solo.event.EventTypes;
import org.b3log.solo.model.Article;
import org.b3log.solo.model.Common;
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.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.1.9, May 4, 2012
* @since 0.3.1
*/
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();
/**
* URL of adding article to Rhythm.
*/
private static final URL ADD_ARTICLE_URL;
static {
try {
ADD_ARTICLE_URL = new URL(SoloServletListener.B3LOG_RHYTHM_ADDRESS + "/add-article.do");
} catch (final MalformedURLException e) {
LOGGER.log(Level.SEVERE, "Creates remote service address[rhythm add article] error!");
throw new IllegalStateException(e);
}
}
@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()});
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));
return;
}
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 article[id={0}, title={1}] to Rhythm",
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));
article.put(Article.ARTICLE_TAGS_REF, originalArticle.getString(Article.ARTICLE_TAGS_REF));
article.put(Article.ARTICLE_AUTHOR_EMAIL, originalArticle.getString(Article.ARTICLE_AUTHOR_EMAIL));
article.put(Article.ARTICLE_CONTENT, originalArticle.getString(Article.ARTICLE_CONTENT));
article.put(Article.ARTICLE_CREATE_DATE, ((Date) originalArticle.get(Article.ARTICLE_CREATE_DATE)).getTime());
article.put(Common.POST_TO_COMMUNITY, originalArticle.getBoolean(Common.POST_TO_COMMUNITY));
// Removes this property avoid to persist
originalArticle.remove(Common.POST_TO_COMMUNITY);
requestJSONObject.put(Article.ARTICLE, article);
requestJSONObject.put(Common.BLOG_VERSION, SoloServletListener.VERSION);
requestJSONObject.put(Common.BLOG, "B3log Solo");
requestJSONObject.put(Preference.BLOG_TITLE, preference.getString(Preference.BLOG_TITLE));
requestJSONObject.put(Preference.BLOG_HOST, blogHost);
httpRequest.setPayload(requestJSONObject.toString().getBytes("UTF-8"));
urlFetchService.fetchAsync(httpRequest);
} catch (final Exception e) {
LOGGER.log(Level.SEVERE, "Sends an article to Rhythm error: {0}", e.getMessage());
}
LOGGER.log(Level.FINER, "Sent an article to Rhythm");
}
/**
* Gets the event type {@linkplain EventTypes#ADD_ARTICLE}.
*
* @return event type
*/
@Override
public String getEventType() {
return EventTypes.ADD_ARTICLE;
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.filter;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.b3log.latke.user.GeneralUser;
import org.b3log.latke.user.UserService;
import org.b3log.latke.user.UserServiceFactory;
import org.b3log.solo.processor.LoginProcessor;
import org.b3log.solo.util.Users;
/**
* Authentication filter.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.3, Oct 4, 2011
* @since 0.3.1
*/
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 {
}
/**
* If the specified request is NOT made by an authenticated user, sends
* error 403.
*
* @param request the specified request
* @param response the specified response
* @param chain filter chain
* @throws IOException io exception
* @throws ServletException servlet exception
*/
@Override
public void doFilter(final ServletRequest request,
final ServletResponse response,
final FilterChain chain) throws IOException,
ServletException {
final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
try {
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);
return;
}
final String currentUserEmail = currentUser.getEmail();
LOGGER.log(Level.FINER, "Current user email[{0}]", currentUserEmail);
if (users.isSoloUser(currentUserEmail)) {
chain.doFilter(request, response);
return;
}
LOGGER.warning("The request has been forbidden");
httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
} catch (final Exception e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
@Override
public void destroy() {
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.filter;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.service.ServiceException;
import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestDispatcher;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.solo.SoloServletListener;
import org.b3log.solo.service.PreferenceQueryService;
import org.json.JSONObject;
/**
* Checks initialization filter.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.9, May 17, 2012
* @since 0.3.1
*/
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 {
}
/**
* If Solo has not been initialized, so redirects to /init.
*
* @param request the specified request
* @param response the specified response
* @param chain filter chain
* @throws IOException io exception
* @throws ServletException servlet exception
*/
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final String requestURI = httpServletRequest.getRequestURI();
LOGGER.log(Level.FINEST, "Request[URI={0}]", requestURI);
try {
if (SoloServletListener.isInited()) {
chain.doFilter(request, response);
return;
}
if ("POST".equalsIgnoreCase(httpServletRequest.getMethod())
&& (Latkes.getContextPath() + "/init").equals(requestURI)) {
// Do initailization
chain.doFilter(request, response);
return;
}
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);
request.setAttribute(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/init");
request.setAttribute(Keys.HttpRequest.REQUEST_METHOD, HTTPRequestMethod.GET.name());
HTTPRequestDispatcher.dispatch(context);
} else {
// XXX: Wrong state of SoloServletListener.isInited()
chain.doFilter(request, response);
}
} catch (final ServiceException e) {
((HttpServletResponse) response).sendError(
HttpServletResponse.SC_NOT_FOUND);
}
}
@Override
public void destroy() {
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.filter;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.time.DateFormatUtils;
import org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.action.AbstractCacheablePageAction;
import org.b3log.latke.cache.PageCaches;
import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.service.LangPropsService;
import org.b3log.latke.service.ServiceException;
import org.b3log.latke.util.StaticResources;
import org.b3log.latke.util.Strings;
import org.b3log.solo.model.Article;
import org.b3log.solo.model.Common;
import org.b3log.solo.model.PageTypes;
import org.b3log.solo.processor.util.TopBars;
import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.impl.ArticleRepositoryImpl;
import org.b3log.solo.util.Articles;
import org.b3log.solo.util.Statistics;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Page cache filter.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.9, Mar 31, 2012
* @since 0.3.1
*/
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 {
}
/**
* Try to write response from cache.
*
* @param request the specified request
* @param response the specified response
* @param chain filter chain
* @throws IOException io exception
* @throws ServletException servlet exception
*/
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
final long startTimeMillis = System.currentTimeMillis();
request.setAttribute(Keys.HttpRequest.START_TIME_MILLIS, startTimeMillis);
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final String requestURI = httpServletRequest.getRequestURI();
LOGGER.log(Level.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);
return;
}
if (!Latkes.isPageCacheEnabled()) {
LOGGER.log(Level.FINEST, "Page cache is disabled");
chain.doFilter(request, response);
return;
}
final String skinDirName = (String) httpServletRequest.getAttribute(Keys.TEMAPLTE_DIR_NAME);
if ("mobile".equals(skinDirName)) {
// Mobile request, bypasses page caching
chain.doFilter(request, response);
return;
}
String pageCacheKey;
final String queryString = httpServletRequest.getQueryString();
pageCacheKey = (String) request.getAttribute(Keys.PAGE_CACHE_KEY);
if (Strings.isEmptyOrNull(pageCacheKey)) {
pageCacheKey = PageCaches.getPageCacheKey(requestURI, queryString);
request.setAttribute(Keys.PAGE_CACHE_KEY, pageCacheKey);
}
final JSONObject cachedPageContentObject = PageCaches.get(pageCacheKey, httpServletRequest);
if (null == cachedPageContentObject) {
LOGGER.log(Level.FINER, "Page cache miss for request URI[{0}]", requestURI);
chain.doFilter(request, response);
return;
}
final String cachedType = cachedPageContentObject.optString(AbstractCacheablePageAction.CACHED_TYPE);
try {
// If cached an article that has view password, dispatches the password form
if (langPropsService.get(PageTypes.ARTICLE).equals(cachedType)
&& cachedPageContentObject.has(AbstractCacheablePageAction.CACHED_PWD)) {
JSONObject article = new JSONObject();
final String articleId = cachedPageContentObject.optString(AbstractCacheablePageAction.CACHED_OID);
article.put(Keys.OBJECT_ID, articleId);
article.put(Article.ARTICLE_VIEW_PWD, cachedPageContentObject.optString(AbstractCacheablePageAction.CACHED_PWD));
if (articles.needViewPwd(httpServletRequest, article)) {
article = articleRepository.get(articleId); // Loads the article entity
final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
try {
httpServletResponse.sendRedirect(Latkes.getServePath()
+ "/console/article-pwd" + articles.buildArticleViewPwdFormParameters(article));
return;
} catch (final Exception e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
}
}
} catch (final Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
chain.doFilter(request, response);
}
try {
LOGGER.log(Level.FINEST, "Writes resposne for page[pageCacheKey={0}] from cache", pageCacheKey);
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
final PrintWriter writer = response.getWriter();
String cachedPageContent = cachedPageContentObject.getString(AbstractCacheablePageAction.CACHED_CONTENT);
final String topBarHTML = TopBars.getTopBarHTML((HttpServletRequest) request, (HttpServletResponse) response);
cachedPageContent = cachedPageContent.replace(Common.TOP_BAR_REPLACEMENT_FLAG, topBarHTML);
final String cachedTitle = cachedPageContentObject.getString(AbstractCacheablePageAction.CACHED_TITLE);
LOGGER.log(Level.FINEST, "Cached value[key={0}, type={1}, title={2}]",
new Object[]{pageCacheKey, cachedType, cachedTitle});
statistics.incBlogViewCount((HttpServletRequest) request);
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);
writer.flush();
writer.close();
} catch (final JSONException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
chain.doFilter(request, response);
} catch (final RepositoryException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
chain.doFilter(request, response);
} catch (final ServiceException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.filter;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestDispatcher;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.solo.model.Article;
import org.b3log.solo.model.Page;
import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.PageRepository;
import org.b3log.solo.repository.impl.ArticleRepositoryImpl;
import org.b3log.solo.repository.impl.PageRepositoryImpl;
import org.b3log.solo.util.Articles;
import org.b3log.solo.util.Permalinks;
import org.json.JSONObject;
/**
* Article/Page permalink filter.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.1.6, May 17, 2012
* @since 0.3.1
* @see org.b3log.solo.processor.ArticleProcessor#showArticle(org.b3log.latke.servlet.HTTPRequestContext,
* javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
* @see org.b3log.solo.processor.PageProcessor#showPage(org.b3log.latke.servlet.HTTPRequestContext)
*/
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 {
}
/**
* Tries to dispatch request to article processor.
*
* @param request the specified request
* @param response the specified response
* @param chain filter chain
* @throws IOException io exception
* @throws ServletException servlet exception
*/
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
final String requestURI = httpServletRequest.getRequestURI();
LOGGER.log(Level.FINER, "Request URI[{0}]", requestURI);
final String contextPath = Latkes.getContextPath();
final String permalink = StringUtils.substringAfter(requestURI, contextPath);
if (Permalinks.invalidPermalinkFormat(permalink)) {
LOGGER.log(Level.FINER, "Skip filter request[URI={0}]", permalink);
chain.doFilter(request, response);
return;
}
JSONObject article;
JSONObject page = null;
try {
article = articleRepository.getByPermalink(permalink);
if (null == article) {
page = pageRepository.getByPermalink(permalink);
}
if (null == page && null == article) {
LOGGER.log(Level.FINER, "Not found article/page with permalink[{0}]", permalink);
chain.doFilter(request, response);
return;
}
} catch (final RepositoryException e) {
LOGGER.log(Level.SEVERE, "Processes article permalink filter failed", e);
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// 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" + articles.buildArticleViewPwdFormParameters(article));
return;
} catch (final Exception e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
}
dispatchToArticleOrPageProcessor(request, response, article, page);
}
/**
* Dispatches the specified request to the specified article or page
* processor with the specified response.
*
* @param request the specified request
* @param response the specified response
* @param article the specified article
* @param page the specified page
* @throws ServletException servlet exception
* @throws IOException io exception
* @see HTTPRequestDispatcher#dispatch(org.b3log.latke.servlet.HTTPRequestContext)
*/
private void dispatchToArticleOrPageProcessor(final ServletRequest request, final ServletResponse response,
final JSONObject article, final JSONObject page)
throws ServletException, IOException {
final HTTPRequestContext context = new HTTPRequestContext();
context.setRequest((HttpServletRequest) request);
context.setResponse((HttpServletResponse) response);
if (null != article) {
request.setAttribute(Article.ARTICLE, article);
request.setAttribute(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/article");
} else {
request.setAttribute(Page.PAGE, page);
request.setAttribute(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/page");
}
request.setAttribute(Keys.HttpRequest.REQUEST_METHOD, HTTPRequestMethod.GET.name());
HTTPRequestDispatcher.dispatch(context);
}
@Override
public void destroy() {
}
}
/**
* Filters for page caching, URL transformation.
*/
package org.b3log.solo.filter;
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.model;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/**
* This class defines all archive date model relevant keys.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.3, Jul 2, 2011
*/
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";
/**
* Key of archive date article count.
*/
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");
/**
* Private default constructor.
*/
private ArchiveDate() {
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.model;
/**
* This class defines all article model relevant keys.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.1.5, Apr 29, 2012
* @since 0.3.1
*/
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 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.
*
* @see Preference#EDITOR_TYPE
*/
public static final String ARTICLE_EDITOR_TYPE = "articleEditorType";
/**
* Private default constructor.
*/
private Article() {
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.model;
/**
* This class defines all cache model relevant keys.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.2, Dec 27, 2010
*/
public final class Cache {
/**
* Cache.
*/
public static final String CACHE = "cache";
/**
* Cached count.
*/
public static final String CACHE_CACHED_COUNT = "cacheCachedCount";
/**
* Cache hit count.
*/
public static final String CACHE_HIT_COUNT = "cacheHitCount";
/**
* Cache hit bytes.
*/
public static final String CACHE_HIT_BYTES = "cacheHitBytes";
/**
* Cached bytes.
*/
public static final String CACHE_CACHED_BYTES = "cacheCachedBytes";
/**
* Cache miss count.
*/
public static final String CACHE_MISS_COUNT = "cacheMissCount";
/**
* Private default constructor.
*/
private Cache() {
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.model;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/**
* This class defines all comment model relevant keys.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.6, Oct 28, 2011
* @since 0.3.1
*/
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";
/**
* Key of original comment user name.
*/
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");
/**
* Private default constructor.
*/
private Comment() {
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.model;
/**
* This class defines all common model relevant keys.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:dongxv.vang@gmail.com">Dongxu Wang</a>
* @version 1.0.4.8, May 4, 2012
* @since 0.3.1
*/
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.
*/
public static final String ARTICLES_VIEW_PWD = "articlesViewPwd";
/**
* Private default constructor.
*/
private Common() {
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.model;
/**
* This class defines all link model relevant keys.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.2, Oct 31, 2011
* @since 0.3.1
*/
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.
*/
public static final String LINK_ORDER = "linkOrder";
/**
* Private default constructor.
*/
private Link() {
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.model;
/**
* This class defines all page model relevant keys.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.5, Apr 29, 2012
* @since 0.3.1
*/
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.
*
* <p>
* Available values:
* <ul>
* <li>link</li>
* No contents (pageContent), if users clicked, just jump to the given address specified by the permalink.
* <li>page</li>
* A normal customized page.
* </ul>
* </p>
*/
public static final String PAGE_TYPE = "pageType";
/**
* Key of open target.
*
* <p>
* Available values:
* <ul>
* <li>_blank</li>
* Opens the linked document in a new window or tab.
* <li>_self</li>
* Opens the linked document in the same frame as it was clicked (this is default).
* <li>_parent</li>
* Opens the linked document in the parent frame.
* <li>_top</li>
* Opens the linked document in the full body of the window.
* <li><i>frame name</i></li>
* Opens the linked document in a named frame.
* </ul>
* See <a href="http://www.w3schools.com/tags/att_a_target.asp">here</a> for more details.
* </p>
*/
public static final String PAGE_OPEN_TARGET = "pageOpenTarget";
/**
* Key of page editor type.
*
* @see Preference#EDITOR_TYPE
*/
public static final String PAGE_EDITOR_TYPE = "pageEditorType";
/**
* Private default constructor.
*/
private Page() {
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.model;
/**
* This class defines all page types language configuration keys.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.2, May 22, 2012
* @since 0.3.1
*/
public final class PageTypes {
/**
* Key of article label.
*/
public static final String ARTICLE = "articleLabel";
/**
* Key of tag article label.
*/
public static final String TAG_ARTICLES = "tagArticlesLabel";
/**
* Key of archive date articles label.
*/
public static final String DATE_ARTICLES = "dateArticlesLabel";
/**
* Key of index articles label.
*/
public static final String INDEX_ARTICLES = "indexArticleLabel";
/**
* Key of all tags label.
*/
public static final String ALL_TAGS = "allTagsLabel";
/**
* Key of author articles label.
*/
public static final String AUTHOR_ARTICLES = "authorArticlesLabel";
/**
* Key of customized page label.
*/
public static final String PAGE = "customizedPageLabel";
/**
* Key of kill browser page label.
*/
public static final String KILL_BROWSER_PAGE = "killBrowserPageLabel";
/**
* Key of user template page label.
*/
public static final String USER_TEMPLATE_PAGE = "userTemplatePageLabel";
/**
* Private default constructor.
*/
private PageTypes() {
}
}
This diff is collapsed.
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.model;
/**
* This class defines all sign model relevant keys.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.0, Dec 29, 2010
*/
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.
*/
public static final String SIGN_HTML = "signHTML";
/**
* Private default constructor.
*/
private Sign() {
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.model;
/**
* This class defines all skin model relevant keys.
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.1, Aug 22, 2010
*/
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.
*/
public static final String SKIN_DIR_NAME = "skinDirName";
/**
* Private default constructor.
*/
private Skin() {
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/**
* Keys.
*/
package org.b3log.solo.model;
This diff is collapsed.
This diff is collapsed.
/**
* <a href="http://b3log-solo.googlecode.com">B3log Solo</a>.
*/
package org.b3log.solo;
This diff is collapsed.
/**
* Plugins.
*/
package org.b3log.solo.plugin;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/**
* Console requests (Articles, Comments, Preference, etc, management) processing.
*/
package org.b3log.solo.processor.console;
/**
* HTTP request processing.
*/
package org.b3log.solo.processor;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment