Commit 10b29982 authored by Liang Ding's avatar Liang Ding

项目结构调整

parent ea57d7fb
/core/target/
/war/gae/target/
/war/mysql/target/
/war/h2/target/
/war/target/
/war/src/main/webapp/WEB-INF/lib/
/war/src/main/webapp/js/admin/latkeAdmin.js
/war/src/main/webapp/js/admin/latkeAdmin.min.js
.idea/ .idea/
.DS_Store .DS_Store
/target/ /target
war/src/main/webapp/skins/* src/main/webapp/skins/*
!war/src/main/webapp/skins/mobile !src/main/webapp/skins/mobile
!war/src/main/webapp/skins/finding !src/main/webapp/skins/finding
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>solo</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
encoding/<project>=UTF-8
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true" />
<attribute name="maven.pomderived" value="true" />
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes"
path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true" />
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes"
path="src/test/java">
<attributes>
<attribute name="optional" value="true" />
<attribute name="maven.pomderived" value="true" />
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src"
output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true" />
</attributes>
</classpathentry>
<classpathentry kind="con"
path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true" />
</attributes>
</classpathentry>
<classpathentry kind="con"
path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true" />
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes" />
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>solo-core</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding//src/test/resources=UTF-8
encoding/<project>=UTF-8
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.6
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
<?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>Captchas</word>
<word>cron</word>
<word>datastore</word>
<word>ftl</word>
<word>Gmail</word>
<word>Gravatar</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>Qiniu</word>
<word>servlet</word>
<word>servlets</word>
<word>sitemap</word>
<word>struct</word>
<word>structs</word>
<word>Swithches</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>clean</goal>
<goal>cobertura:cobertura</goal>
<goal>coveralls:report</goal>
</goals>
</action>
<action>
<actionName>CUSTOM-jacobe-jacobe</actionName>
<displayName>jacobe-jacobe</displayName>
<goals>
<goal>jacobe:jacobe</goal>
</goals>
</action>
</actions>
<?xml version="1.0" encoding="UTF-8"?>
<!--
Description: Solo core.
Version: 2.5.1.7, Sep 16, 2015
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>
<artifactId>solo-core</artifactId>
<packaging>jar</packaging>
<name>Solo (Core)</name>
<description>Solo Core.</description>
<parent>
<groupId>org.b3log</groupId>
<artifactId>solo</artifactId>
<version>1.0.0</version>
</parent>
<dependencies>
<dependency>
<groupId>org.b3log</groupId>
<artifactId>latke</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.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>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>etc/</exclude>
</excludes>
</resource>
</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>
<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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<configuration>
<show>private</show>
</configuration>
<executions>
<execution>
<phase>process-sources</phase>
</execution>
</executions>
</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>
<skip>false</skip>
</configuration>
<executions>
<!-- <execution> <phase>compile</phase> <goals> <goal>checkstyle</goal>
</goals> </execution> -->
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>linux</id>
<activation>
<os>
<family>linux</family>
</os>
</activation>
<properties>
<jacobeExecutable>
../src/main/resources/etc/jacobe/linux/jacobe
</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>
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.b3log:latke:1.1.0" level="project" />
<orderEntry type="library" name="Maven: javax.enterprise:cdi-api:1.0" level="project" />
<orderEntry type="library" name="Maven: org.jboss.interceptor:jboss-interceptor-api:1.1" level="project" />
<orderEntry type="library" name="Maven: javax.annotation:jsr250-api:1.0" level="project" />
<orderEntry type="library" name="Maven: javax.inject:javax.inject:1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.5" level="project" />
<orderEntry type="library" name="Maven: javax.el:el-api:1.0" level="project" />
<orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.20" level="project" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:1.4" level="project" />
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.5" level="project" />
<orderEntry type="library" name="Maven: javassist:javassist:3.12.1.GA" level="project" />
<orderEntry type="library" name="Maven: com.jolbox:bonecp:0.8.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:15.0" level="project" />
<orderEntry type="library" name="Maven: c3p0:c3p0:0.9.1.2" level="project" />
<orderEntry type="library" name="Maven: com.h2database:h2:1.4.182" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid:1.0.11" level="project" />
<orderEntry type="library" name="Maven: org.jboss:jboss-vfs:3.1.0.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.0.0.CR1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:servlet-api:2.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.testng:testng:6.1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:3.8.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.beanshell:bsh:2.0b4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.beust:jcommander:1.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.yaml:snakeyaml:1.6" level="project" />
<orderEntry type="library" name="Maven: org.jsoup:jsoup:1.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.b3log:latke-gae:1.1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.google.appengine:appengine-api-1.0-sdk:1.8.1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.google.appengine:appengine-api-labs:1.8.1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.google.appengine:appengine-api-stubs:1.8.1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.google.appengine:appengine-testing:1.8.1.1" level="project" />
<orderEntry type="library" name="Maven: org.tautua.markdownpapers:markdownpapers-core:1.3.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-log4j12:1.7.5" level="project" />
<orderEntry type="library" name="Maven: log4j:log4j:1.2.17" level="project" />
</component>
</module>
\ No newline at end of file
/**
* <a href="http://www.xmlrpc.com/metaWeblogApi">MetaWeblog API</a> requests
* processing.
*/
package org.b3log.solo.api.metaweblog;
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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.api.symphony;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.b3log.latke.Keys;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.model.User;
import org.b3log.latke.service.ServiceException;
import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.annotation.RequestProcessing;
import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.JSONRenderer;
import org.b3log.latke.util.Requests;
import org.b3log.solo.model.Article;
import org.b3log.solo.model.Common;
import org.b3log.solo.model.Preference;
import org.b3log.solo.service.ArticleMgmtService;
import org.b3log.solo.service.ArticleQueryService;
import org.b3log.solo.service.PreferenceQueryService;
import org.b3log.solo.service.UserQueryService;
import org.b3log.solo.util.QueryResults;
import org.json.JSONObject;
import org.jsoup.Jsoup;
/**
* Article receiver (from B3log Symphony).
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.5, Mar 18, 2013
* @since 0.5.5
*/
@RequestProcessor
public class ArticleReceiver {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(ArticleReceiver.class.getName());
/**
* Preference query service.
*/
@Inject
private PreferenceQueryService preferenceQueryService;
/**
* Article management service.
*/
@Inject
private ArticleMgmtService articleMgmtService;
/**
* Article query service.
*/
@Inject
private ArticleQueryService articleQueryService;
/**
* User query service.
*/
@Inject
private UserQueryService userQueryService;
/**
* Article abstract length.
*/
private static final int ARTICLE_ABSTRACT_LENGTH = 500;
/**
* Adds an article with the specified request.
*
* <p>
* Renders the response with a json object, for example,
* <pre>
* {
* "sc": boolean,
* "oId": "", // Generated article id
* "msg": ""
* }
* </pre>
* </p>
*
* @param request the specified http servlet request, for example,
* <pre>
* {
* "article": {
* "oId": "",
* "articleTitle": "",
* "articleContent": "",
* "articleTags": "tag1,tag2,tag3",
* "userB3Key": "",
* "articleEditorType": ""
* }
* }
* </pre>
* @param response the specified http servlet response
* @param context the specified http request context
* @throws Exception exception
*/
@RequestProcessing(value = "/apis/symphony/article", method = HTTPRequestMethod.POST)
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();
try {
final JSONObject requestJSONObject = Requests.parseRequestJSONObject(request, response);
final JSONObject article = requestJSONObject.optJSONObject(Article.ARTICLE);
final String userB3Key = article.optString("userB3Key");
final JSONObject preference = preferenceQueryService.getPreference();
if (!userB3Key.equals(preference.optString(Preference.KEY_OF_SOLO))) {
LOGGER.log(Level.WARN, "B3 key not match, ignored add article");
return;
}
article.remove("userB3Key");
final JSONObject admin = userQueryService.getAdmin();
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 {
article.put(Article.ARTICLE_ABSTRACT, plainTextContent);
}
article.put(Article.ARTICLE_IS_PUBLISHED, true);
article.put(Common.POST_TO_COMMUNITY, false); // Do not send to rhythm
article.put(Article.ARTICLE_COMMENTABLE, true);
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://hacpai.com/article/" + articleId
+ "' target='_blank'>黑客派</a></i></p>";
article.put(Article.ARTICLE_CONTENT, content);
articleMgmtService.addArticle(requestJSONObject);
ret.put(Keys.OBJECT_ID, articleId);
ret.put(Keys.MSG, "add article succ");
ret.put(Keys.STATUS_CODE, true);
renderer.setJSONObject(ret);
} catch (final ServiceException e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
final JSONObject jsonObject = QueryResults.defaultResult();
renderer.setJSONObject(jsonObject);
jsonObject.put(Keys.MSG, e.getMessage());
}
}
/**
* Updates an article with the specified request.
*
* <p>
* Renders the response with a json object, for example,
* <pre>
* {
* "sc": boolean,
* "msg": ""
* }
* </pre>
* </p>
*
* @param request the specified http servlet request, for example,
* <pre>
* {
* "article": {
* "oId": "", // Symphony Article#clientArticleId
* "articleTitle": "",
* "articleContent": "",
* "articleTags": "tag1,tag2,tag3",
* "userB3Key": "",
* "articleEditorType": ""
* }
* }
* </pre>
* @param response the specified http servlet response
* @param context the specified http request context
* @throws Exception exception
*/
@RequestProcessing(value = "/apis/symphony/article", method = HTTPRequestMethod.PUT)
public void updateArticle(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);
try {
final JSONObject requestJSONObject = Requests.parseRequestJSONObject(request, response);
final JSONObject article = requestJSONObject.optJSONObject(Article.ARTICLE);
final String userB3Key = article.optString("userB3Key");
final JSONObject preference = preferenceQueryService.getPreference();
if (!userB3Key.equals(preference.optString(Preference.KEY_OF_SOLO))) {
LOGGER.log(Level.WARN, "B3 key not match, ignored update article");
return;
}
article.remove("userB3Key");
final String articleId = article.getString(Keys.OBJECT_ID);
if (null == articleQueryService.getArticleById(articleId)) {
ret.put(Keys.MSG, "No found article[oId=" + articleId + "] to update");
ret.put(Keys.STATUS_CODE, false);
return;
}
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 {
article.put(Article.ARTICLE_ABSTRACT, plainTextContent);
}
article.put(Article.ARTICLE_IS_PUBLISHED, true);
article.put(Common.POST_TO_COMMUNITY, false); // Do not send to rhythm
article.put(Article.ARTICLE_COMMENTABLE, true);
article.put(Article.ARTICLE_VIEW_PWD, "");
String content = article.getString(Article.ARTICLE_CONTENT);
content += "<br/><br/><p style='font-size: 12px;'><i>该文章同步自 <a href='http://hacpai.com/article/" + articleId
+ "' target='_blank'>黑客派</a></i></p>";
article.put(Article.ARTICLE_CONTENT, content);
articleMgmtService.updateArticle(requestJSONObject);
ret.put(Keys.MSG, "update article succ");
ret.put(Keys.STATUS_CODE, true);
} catch (final ServiceException e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
final JSONObject jsonObject = QueryResults.defaultResult();
renderer.setJSONObject(jsonObject);
jsonObject.put(Keys.MSG, e.getMessage());
}
}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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 javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.time.DateUtils;
import org.b3log.latke.Latkes;
import org.b3log.latke.RuntimeMode;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.model.User;
import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.annotation.RequestProcessing;
import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.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="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.4, Feb 1, 2013
* @since 0.4.0
*/
@RequestProcessor
public class ArticleGenerator {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(ArticleGenerator.class.getName());
/**
* Article management service.
*/
@Inject
private ArticleMgmtService articleMgmtService;
/**
* User query service.
*/
@Inject
private UserQueryService userQueryService;
/**
* 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.WARN, "Article generation just for development mode, " + "current runtime mode is [{0}]",
Latkes.getRuntimeMode());
response.sendRedirect(Latkes.getServePath());
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 JSONObject admin = userQueryService.getAdmin();
final String authorEmail = admin.optString(User.USER_EMAIL);
for (int i = 0; i < num; i++) {
final JSONObject article = new JSONObject();
article.put(Article.ARTICLE_TITLE, "article title" + i);
article.put(Article.ARTICLE_ABSTRACT, "article" + i + " abstract");
final int deviationTag = 3;
article.put(Article.ARTICLE_TAGS_REF, "taga,tagb,tag" + i % deviationTag);
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);
final int deviationBase = 5;
final int deviationDay = -(Integer.valueOf(String.valueOf(i).substring(0, 1)) % deviationBase);
final Date date = DateUtils.addMonths(new Date(), deviationDay);
article.put(Article.ARTICLE_CREATE_DATE, date);
article.put(Article.ARTICLE_UPDATE_DATE, 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.ERROR, e.getMessage(), e);
}
Stopwatchs.end();
response.sendRedirect(Latkes.getServePath());
}
}
/**
* Development usage.
*
* <p>
* All functions in this package just for development mode.
* </p>
*/
package org.b3log.solo.dev;
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.7, May 30, 2014
* @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 a before render article event.
*/
public static final String BEFORE_RENDER_ARTICLE = "Before Render 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.
*/
public static final String REMOVE_COMMENT = "Remove Comment";
/**
* Private default constructor.
*/
private EventTypes() {}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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 org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.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.Article;
import org.b3log.solo.model.Comment;
import org.b3log.solo.model.Preference;
import org.b3log.solo.repository.CommentRepository;
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="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.1.6, May 17, 2013
* @since 0.3.1
*/
public final class ArticleCommentReplyNotifier extends AbstractEventListener<JSONObject> {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(ArticleCommentReplyNotifier.class.getName());
/**
* Mail service.
*/
private MailService mailService = MailServiceFactory.getMailService();
@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.DEBUG, "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.DEBUG, "This comment[id={0}] is not a reply", comment.optString(Keys.OBJECT_ID));
return;
}
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final PreferenceQueryService preferenceQueryService = beanManager.getReference(PreferenceQueryService.class);
final CommentRepository commentRepository = beanManager.getReference(CommentRepositoryImpl.class);
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 articleLink = Latkes.getServePath() + article.getString(Article.ARTICLE_PERMALINK);
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}", Latkes.getServePath() + commentSharpURL).replace(
"${replyContent}", commentContent);
message.setHtmlBody(mailBody);
LOGGER.log(Level.DEBUG, "Sending a mail[mailSubject={0}, mailBody=[{1}] to [{2}]",
new Object[] {mailSubject, mailBody, originalCommentEmail});
mailService.send(message);
} catch (final Exception e) {
LOGGER.log(Level.ERROR, 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) 2010-2015, b3log.org
*
* 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 org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.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.Page;
import org.b3log.solo.model.Preference;
import org.b3log.solo.repository.CommentRepository;
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="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.1.2, May 17, 2013
* @since 0.3.1
*/
public final class PageCommentReplyNotifier extends AbstractEventListener<JSONObject> {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(PageCommentReplyNotifier.class.getName());
/**
* Mail service.
*/
private MailService mailService = MailServiceFactory.getMailService();
@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.DEBUG, "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.DEBUG, "This comment[id={0}] is not a reply", comment.optString(Keys.OBJECT_ID));
return;
}
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final PreferenceQueryService preferenceQueryService = beanManager.getReference(PreferenceQueryService.class);
final CommentRepository commentRepository = beanManager.getReference(CommentRepositoryImpl.class);
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 pageLink = Latkes.getServePath() + page.getString(Page.PAGE_PERMALINK);
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}", Latkes.getServePath() + commentSharpURL).replace(
"${replyContent}", commentContent);
message.setHtmlBody(mailBody);
LOGGER.log(Level.DEBUG, "Sending a mail[mailSubject={0}, mailBody=[{1}] to [{2}]",
new Object[] {mailSubject, mailBody, originalCommentEmail});
mailService.send(message);
} catch (final Exception e) {
LOGGER.log(Level.ERROR, 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) 2010-2015, b3log.org
*
* 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 org.b3log.latke.Latkes;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.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="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.3, May 17, 2013
* @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;
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final PreferenceQueryService preferenceQueryService = beanManager.getReference(PreferenceQueryService.class);
try {
final JSONObject article = eventData.getJSONObject(Article.ARTICLE);
articleTitle = article.getString(Article.ARTICLE_TITLE);
final JSONObject preference = preferenceQueryService.getPreference();
final String blogTitle = preference.getString(Preference.BLOG_TITLE);
if (Latkes.getServePath().contains("localhost")) {
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;
}
final String articlePermalink = Latkes.getServePath() + article.getString(Article.ARTICLE_PERMALINK);
final String spec = "http://blogsearch.google.com/ping?name=" + URLEncoder.encode(blogTitle, "UTF-8") + "&url="
+ URLEncoder.encode(Latkes.getServePath(), "UTF-8") + "&changesURL=" + URLEncoder.encode(articlePermalink, "UTF-8");
LOGGER.log(Level.DEBUG, "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.ERROR, "Ping Google Blog Search Service fail while adding an article[title=" + articleTitle + "]", e);
}
}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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 org.b3log.latke.Latkes;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.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="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.3, May 17, 2013
* @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;
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final PreferenceQueryService preferenceQueryService = beanManager.getReference(PreferenceQueryService.class);
try {
final JSONObject article = eventData.getJSONObject(Article.ARTICLE);
articleTitle = article.getString(Article.ARTICLE_TITLE);
final JSONObject preference = preferenceQueryService.getPreference();
final String blogTitle = preference.getString(Preference.BLOG_TITLE);
if (Latkes.getServePath().contains("localhost")) {
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;
}
final String articlePermalink = Latkes.getServePath() + article.getString(Article.ARTICLE_PERMALINK);
final String spec = "http://blogsearch.google.com/ping?name=" + URLEncoder.encode(blogTitle, "UTF-8") + "&url="
+ URLEncoder.encode(Latkes.getServePath(), "UTF-8") + "&changesURL=" + URLEncoder.encode(articlePermalink, "UTF-8");
LOGGER.log(Level.DEBUG,
"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.ERROR, "Ping Google Blog Search Service fail while updating an " + "article[title=" + articleTitle + "]", e);
}
}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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 org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.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.service.PluginMgmtService;
/**
* This listener is responsible for refreshing plugin after every loaded.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.1, Nov 28, 2011
* @since 0.3.1
*/
public final class PluginRefresher extends AbstractEventListener<List<AbstractPlugin>> {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(PluginRefresher.class.getName());
@Override
public void action(final Event<List<AbstractPlugin>> event) throws EventException {
final List<AbstractPlugin> plugins = event.getData();
LOGGER.log(Level.DEBUG, "Processing an event[type={0}, data={1}] in listener[className={2}]",
new Object[] {event.getType(), plugins, PluginRefresher.class.getName()});
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final PluginRepository pluginRepository = beanManager.getReference(PluginRepositoryImpl.class);
final Transaction transaction = pluginRepository.beginTransaction();
try {
final PluginMgmtService pluginMgmtService = beanManager.getReference(PluginMgmtService.class);
pluginMgmtService.refresh(plugins);
transaction.commit();
} catch (final Exception e) {
if (transaction.isActive()) {
transaction.rollback();
}
LOGGER.log(Level.ERROR, "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) 2010-2015, b3log.org
*
* 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 org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.urlfetch.HTTPRequest;
import org.b3log.latke.urlfetch.URLFetchService;
import org.b3log.latke.urlfetch.URLFetchServiceFactory;
import org.b3log.latke.util.Strings;
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.
*
* <p>
* The B3log Rhythm article update interface: http://rhythm.b3log.org/article (POST).
* </p>
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author ArmstrongCN
* @version 1.0.2.7, Jun 13, 2013
* @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();
/**
* URL of adding article to Rhythm.
*/
private static final URL ADD_ARTICLE_URL;
static {
try {
ADD_ARTICLE_URL = new URL(SoloServletListener.B3LOG_RHYTHM_SERVE_PATH + "/article");
} catch (final MalformedURLException e) {
LOGGER.log(Level.ERROR, "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.DEBUG, "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.DEBUG, "Ignores post article[title={0}] to Rhythm", originalArticle.getString(Article.ARTICLE_TITLE));
return;
}
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final PreferenceQueryService preferenceQueryService = beanManager.getReference(PreferenceQueryService.class);
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) {
throw new EventException("Not found preference");
}
if (!Strings.isEmptyOrNull(originalArticle.optString(Article.ARTICLE_VIEW_PWD))) {
return;
}
if (Latkes.getServePath().contains("localhost")) {
LOGGER.log(Level.INFO, "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("blogHost", Latkes.getServePath());
requestJSONObject.put("userB3Key", preference.optString(Preference.KEY_OF_SOLO));
requestJSONObject.put("clientAdminEmail", preference.optString(Preference.ADMIN_EMAIL));
requestJSONObject.put("clientRuntimeEnv", Latkes.getRuntimeEnv().name());
httpRequest.setPayload(requestJSONObject.toString().getBytes("UTF-8"));
urlFetchService.fetchAsync(httpRequest);
} catch (final Exception e) {
LOGGER.log(Level.ERROR, "Sends an article to Rhythm error: {0}", e.getMessage());
}
LOGGER.log(Level.DEBUG, "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) 2010-2015, b3log.org
*
* 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 org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.urlfetch.HTTPRequest;
import org.b3log.latke.urlfetch.URLFetchService;
import org.b3log.latke.urlfetch.URLFetchServiceFactory;
import org.b3log.latke.util.Strings;
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 updating article to B3log Rhythm.
*
* <p>
* The B3log Rhythm article update interface: http://rhythm.b3log.org/article (PUT).
* </p>
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.1, May 17, 2013
* @since 0.6.0
*/
public final class ArticleUpdater extends AbstractEventListener<JSONObject> {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(ArticleUpdater.class.getName());
/**
* URL fetch service.
*/
private final URLFetchService urlFetchService = URLFetchServiceFactory.getURLFetchService();
/**
* URL of updating article to Rhythm.
*/
private static final URL UPDATE_ARTICLE_URL;
static {
try {
UPDATE_ARTICLE_URL = new URL(SoloServletListener.B3LOG_RHYTHM_SERVE_PATH + "/article");
} catch (final MalformedURLException e) {
LOGGER.log(Level.ERROR, "Creates remote service address[rhythm update article] error!");
throw new IllegalStateException(e);
}
}
@Override
public void action(final Event<JSONObject> event) throws EventException {
final JSONObject data = event.getData();
LOGGER.log(Level.DEBUG, "Processing an event[type={0}, data={1}] in listener[className={2}]",
new Object[]{event.getType(), data, ArticleUpdater.class.getName()});
try {
final JSONObject originalArticle = data.getJSONObject(Article.ARTICLE);
if (!originalArticle.getBoolean(Article.ARTICLE_IS_PUBLISHED)) {
LOGGER.log(Level.DEBUG, "Ignores post article[title={0}] to Rhythm", originalArticle.getString(Article.ARTICLE_TITLE));
return;
}
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final PreferenceQueryService preferenceQueryService = beanManager.getReference(PreferenceQueryService.class);
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) {
throw new EventException("Not found preference");
}
if (!Strings.isEmptyOrNull(originalArticle.optString(Article.ARTICLE_VIEW_PWD))) {
return;
}
if (Latkes.getServePath().contains("localhost")) {
LOGGER.log(Level.INFO, "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(UPDATE_ARTICLE_URL);
httpRequest.setRequestMethod(HTTPRequestMethod.PUT);
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("blogHost", Latkes.getServerHost() + ":" + Latkes.getServerPort());
requestJSONObject.put("userB3Key", preference.optString(Preference.KEY_OF_SOLO));
requestJSONObject.put("clientAdminEmail", preference.optString(Preference.ADMIN_EMAIL));
requestJSONObject.put("clientRuntimeEnv", Latkes.getRuntimeEnv().name());
httpRequest.setPayload(requestJSONObject.toString().getBytes("UTF-8"));
urlFetchService.fetchAsync(httpRequest);
} catch (final Exception e) {
LOGGER.log(Level.ERROR, "Sends an article to Rhythm error: {0}", e.getMessage());
}
LOGGER.log(Level.DEBUG, "Sent an article to Rhythm");
}
/**
* Gets the event type {@linkplain EventTypes#UPDATE_ARTICLE}.
*
* @return event type
*/
@Override
public String getEventType() {
return EventTypes.UPDATE_ARTICLE;
}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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.symphony;
import java.net.MalformedURLException;
import java.net.URL;
import org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.event.AbstractEventListener;
import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException;
import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.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.event.rhythm.ArticleSender;
import org.b3log.solo.model.Comment;
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.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.3, Mar 5, 2013
* @since 0.5.5
*/
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();
/**
* URL of adding comment to Symphony.
*/
private static final URL ADD_COMMENT_URL;
static {
try {
ADD_COMMENT_URL = new URL(SoloServletListener.B3LOG_SYMPHONY_SERVE_PATH + "/solo/comment");
} catch (final MalformedURLException e) {
LOGGER.log(Level.ERROR, "Creates remote service address[symphony add comment] error!");
throw new IllegalStateException(e);
}
}
@Override
public void action(final Event<JSONObject> event) throws EventException {
final JSONObject data = event.getData();
LOGGER.log(Level.DEBUG, "Processing an event[type={0}, data={1}] in listener[className={2}]",
new Object[] {event.getType(), data, ArticleSender.class.getName()});
try {
final JSONObject originalComment = data.getJSONObject(Comment.COMMENT);
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final PreferenceQueryService preferenceQueryService = beanManager.getReference(PreferenceQueryService.class);
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) {
throw new EventException("Not found preference");
}
if (Latkes.getServePath().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)});
return;
}
final HTTPRequest httpRequest = new HTTPRequest();
httpRequest.setURL(ADD_COMMENT_URL);
httpRequest.setRequestMethod(HTTPRequestMethod.POST);
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));
comment.put(Comment.COMMENT_CONTENT, originalComment.getString(Comment.COMMENT_CONTENT));
comment.put("articleId", originalComment.getString(Comment.COMMENT_ON_ID));
requestJSONObject.put(Comment.COMMENT, comment);
requestJSONObject.put("clientVersion", SoloServletListener.VERSION);
requestJSONObject.put("clientRuntimeEnv", Latkes.getRuntimeEnv().name());
requestJSONObject.put("clientName", "B3log Solo");
requestJSONObject.put("clientHost", Latkes.getServerHost() + ":" + Latkes.getServerPort());
requestJSONObject.put("clientAdminEmail", preference.optString(Preference.ADMIN_EMAIL));
requestJSONObject.put("userB3Key", preference.optString(Preference.KEY_OF_SOLO));
httpRequest.setPayload(requestJSONObject.toString().getBytes("UTF-8"));
urlFetchService.fetchAsync(httpRequest);
} catch (final Exception e) {
LOGGER.log(Level.ERROR, "Sends a comment to Symphony error: {0}", e.getMessage());
}
LOGGER.log(Level.DEBUG, "Sent a comment to Symphony");
}
/**
* 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) 2010-2015, b3log.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.filter;
import java.io.IOException;
import 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.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.model.Role;
import org.b3log.latke.model.User;
import org.b3log.solo.service.UserMgmtService;
import org.b3log.solo.service.UserQueryService;
import org.json.JSONObject;
/**
* Authentication filter.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.4, Jul 10, 2013
* @since 0.3.1
*/
public final class AuthFilter implements Filter {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(AuthFilter.class.getName());
@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;
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final UserMgmtService userMgmtService = beanManager.getReference(UserMgmtService.class);
final UserQueryService userQueryService = beanManager.getReference(UserQueryService.class);
try {
userMgmtService.tryLogInWithCookie(httpServletRequest, httpServletResponse);
final JSONObject currentUser = userQueryService.getCurrentUser(httpServletRequest);
if (null == currentUser) {
LOGGER.warn("The request has been forbidden");
httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
final String userRole = currentUser.optString(User.USER_ROLE);
if (Role.VISITOR_ROLE.equals(userRole)) {
LOGGER.warn("The request [Visitor] has been forbidden");
httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
chain.doFilter(request, response);
} catch (final IOException e) {
LOGGER.log(Level.ERROR, "Auth filter failed", e);
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
@Override
public void destroy() {}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.filter;
import java.io.IOException;
import 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.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.servlet.DispatcherServlet;
import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.HttpControl;
import org.b3log.latke.servlet.renderer.HTTP500Renderer;
import org.b3log.solo.service.InitService;
/**
* Checks initialization filter.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.1.1, Sep 10, 2013
* @since 0.3.1
*/
public final class InitCheckFilter implements Filter {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(InitCheckFilter.class.getName());
@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.TRACE, "Request[URI={0}]", requestURI);
// If requests Latke Remote APIs, skips this filter
if (requestURI.startsWith(Latkes.getContextPath() + "/latke/remote")) {
chain.doFilter(request, response);
return;
}
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final InitService initService = beanManager.getReference(InitService.class);
if (initService.isInited()) {
chain.doFilter(request, response);
return;
}
if ("POST".equalsIgnoreCase(httpServletRequest.getMethod()) && (Latkes.getContextPath() + "/init").equals(requestURI)) {
// Do initailization
chain.doFilter(request, response);
return;
}
LOGGER.log(Level.INFO, "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());
final HttpControl httpControl = new HttpControl(DispatcherServlet.SYS_HANDLER.iterator(), context);
try {
httpControl.nextHandler();
} catch (final Exception e) {
context.setRenderer(new HTTP500Renderer(e));
}
DispatcherServlet.result(context);
}
@Override
public void destroy() {}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.b3log.solo.filter;
import java.io.IOException;
import 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.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.Lifecycle;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.servlet.DispatcherServlet;
import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.HttpControl;
import org.b3log.latke.servlet.renderer.HTTP500Renderer;
import org.b3log.solo.model.Article;
import org.b3log.solo.model.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.service.ArticleQueryService;
import org.b3log.solo.service.PermalinkQueryService;
import org.json.JSONObject;
/**
* Article/Page permalink filter.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.1.7, Jan 8, 2013
* @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());
@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.DEBUG, "Request URI[{0}]", requestURI);
final String contextPath = Latkes.getContextPath();
final String permalink = StringUtils.substringAfter(requestURI, contextPath);
if (PermalinkQueryService.invalidPermalinkFormat(permalink)) {
LOGGER.log(Level.DEBUG, "Skip filter request[URI={0}]", permalink);
chain.doFilter(request, response);
return;
}
JSONObject article;
JSONObject page = null;
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
try {
final ArticleRepository articleRepository = beanManager.getReference(ArticleRepositoryImpl.class);
article = articleRepository.getByPermalink(permalink);
if (null == article) {
final PageRepository pageRepository = beanManager.getReference(PageRepositoryImpl.class);
page = pageRepository.getByPermalink(permalink);
}
if (null == page && null == article) {
LOGGER.log(Level.DEBUG, "Not found article/page with permalink[{0}]", permalink);
chain.doFilter(request, response);
return;
}
} catch (final RepositoryException e) {
LOGGER.log(Level.ERROR, "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
final ArticleQueryService articleQueryService = beanManager.getReference(ArticleQueryService.class);
if (null != article && articleQueryService.needViewPwd(httpServletRequest, article)) {
try {
httpServletResponse.sendRedirect(
Latkes.getServePath() + "/console/article-pwd?articleId=" + article.optString(Keys.OBJECT_ID));
return;
} catch (final Exception e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
}
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());
final HttpControl httpControl = new HttpControl(DispatcherServlet.SYS_HANDLER.iterator(), context);
try {
httpControl.nextHandler();
} catch (final Exception e) {
context.setRenderer(new HTTP500Renderer(e));
}
DispatcherServlet.result(context);
}
@Override
public void destroy() {}
}
/**
* Filters for page caching, URL transformation.
*/
package org.b3log.solo.filter;
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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 archive date model relevant keys.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.4, Jan 18, 2013
*/
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";
/**
* Private default constructor.
*/
private ArchiveDate() {}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.1.6, Jan 8, 2013
* @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 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.
*
* @see Preference#EDITOR_TYPE
*/
public static final String ARTICLE_EDITOR_TYPE = "articleEditorType";
/**
* Private default constructor.
*/
private Article() {}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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 comment model relevant keys.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.7, Jan 18, 2013
* @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";
/**
* Private default constructor.
*/
private Comment() {}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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="http://88250.b3log.org">Liang Ding</a>
* @author <a href="mailto:dongxu.wang@acm.org">Dongxu Wang</a>
* @version 1.3.5.1, Jun 13, 2015
* @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";
/**
* Previous article abstract.
*/
public static final String PREVIOUS_ARTICLE_ABSTRACT = "previousArticleAbstract";
/**
* Next article title.
*/
public static final String NEXT_ARTICLE_TITLE = "nextArticleTitle";
/**
* Next article abstract.
*/
public static final String NEXT_ARTICLE_ABSTRACT = "nextArticleAbstract";
/**
* Is index.
*/
public static final String IS_INDEX = "isIndex";
/**
* 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 thumbnail URL.
*/
public static final String AUTHOR_THUMBNAIL_URL = "authorThumbnailURL";
/**
* 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 favicon API.
*/
public static final String FAVICON_API = "faviconAPI";
/**
* 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 is visitor.
*/
public static final String IS_VISITOR = "isVisitor";
/**
* 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 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 = "topBarReplacement";
/**
* 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";
/**
* Key of Gravatar.
*/
public static final String GRAVATAR = "gravatar";
/**
* Private default constructor.
*/
private Common() {
}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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="http://88250.b3log.org">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) 2010-2015, b3log.org
*
* 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 option model relevant keys.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.0, Sep 12, 2015
* @since 0.6.0
*/
public final class Option {
/**
* Option.
*/
public static final String OPTION = "option";
/**
* Options.
*/
public static final String OPTIONS = "options";
/**
* Key of option value.
*/
public static final String OPTION_VALUE = "optionValue";
/**
* Key of option category.
*/
public static final String OPTION_CATEGORY = "optionCategory";
// oId constants
/**
* Key of broadcast chance expiration time.
*/
public static final String ID_C_BROADCAST_CHANCE_EXPIRATION_TIME = "broadcastChanceExpirationTime";
/**
* Key of Qiniu access key.
*/
public static final String ID_C_QINIU_ACCESS_KEY = "qiniuAccessKey";
/**
* Key of Qiniu secret key.
*/
public static final String ID_C_QINIU_SECRET_KEY = "qiniuSecretKey";
/**
* Key of Qiniu domain.
*/
public static final String ID_C_QINIU_DOMAIN = "qiniuDomain";
/**
* Key of Qiniu bucket.
*/
public static final String ID_C_QINIU_BUCKET = "qiniuBucket";
// Category constants
/**
* Broadcast.
*/
public static final String CATEGORY_C_BROADCAST = "broadcast";
/**
* Qiniu.
*/
public static final String CATEGORY_C_QINIU = "qiniu";
/**
* Private constructor.
*/
private Option() {
}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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="http://88250.b3log.org">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) 2010-2015, b3log.org
*
* 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 enumeration defines all page types language configuration keys.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 2.0.0.0, Aug 28, 2012
* @since 0.3.1
*/
public enum PageTypes {
/**
* Article.
*/
ARTICLE("articleLabel", "Article"),
/**
* Tag articles.
*/
TAG_ARTICLES("tagArticlesLabel", "TagArticles"),
/**
* Date articles.
*/
DATE_ARTICLES("dateArticlesLabel", "DateArticles"),
/**
* Index.
*/
INDEX("indexArticleLabel", "Index"),
/**
* Tags.
*/
TAGS("allTagsLabel", "Tags"),
/**
* Author articles.
*/
AUTHOR_ARTICLES("authorArticlesLabel", "AuthorArticles"),
/**
* Page.
*/
PAGE("customizedPageLabel", "Page"),
/**
* Kill browser page.
*/
KILL_BROWSER("killBrowserPageLabel", "KillBrowser"),
/**
* User template.
*/
USER_TEMPLATE("userTemplatePageLabel", "UserTemplate");
/**
* Language label.
*/
private final String langLabel;
/**
* Type name.
*/
private final String typeName;
/**
* Gets the language label.
*
* @return language label
*/
public String getLangeLabel() {
return langLabel;
}
/**
* Gets the type name.
*
* @return type name
*/
public String getTypeName() {
return typeName;
}
/**
* Constructs a page type with the specified language label and type name.
*
* @param langLabel the specified language label
* @param typeName the specified type name
*/
private PageTypes(final String langLabel, final String typeName) {
this.langLabel = langLabel;
this.typeName = typeName;
}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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="http://88250.b3log.org">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) 2010-2015, b3log.org
*
* 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="http://88250.b3log.org">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() {}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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 statistic model relevant keys.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.1, Dec 9, 2010
*/
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";
/**
* Key of blog comment count.
*/
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";
/**
* Key of blog article count.
*/
public static final String STATISTIC_BLOG_ARTICLE_COUNT = "statisticBlogArticleCount";
/**
* Key of blog published article count.
*/
public static final String STATISTIC_PUBLISHED_ARTICLE_COUNT = "statisticPublishedBlogArticleCount";
/**
* Private default constructor.
*/
private Statistic() {}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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 tag model relevant keys.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.7, Dec 3, 2010
*/
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";
/**
* Private default constructor.
*/
private Tag() {}
}
/*
* Copyright (c) 2010-2015, b3log.org
*
* 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 ext of user model relevant keys.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.0, Feb 21, 2012
* @since 0.4.1
* @see org.b3log.latke.model.User
*/
public final class UserExt {
/**
* Key of user article count.
*/
public static final String USER_ARTICLE_COUNT = "userArticleCount";
/**
* Key of user article count.
*/
public static final String USER_PUBLISHED_ARTICLE_COUNT = "userPublishedArticleCount";
/**
* Private constructor.
*/
private UserExt() {}
}
/**
* <a href="https://github.com/b3log/solo">Solo</a>.
*/
package org.b3log.solo;
/**
* Plugins.
*/
package org.b3log.solo.plugin;
/**
* 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.
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