Commit 7b34fc92 authored by Liang Ding's avatar Liang Ding

🔥 Fix #12411

parent 549ebbb4
......@@ -16,7 +16,6 @@
package org.b3log.solo.processor;
import org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.ioc.LatkeBeanManager;
import org.b3log.latke.ioc.inject.Inject;
import org.b3log.latke.logging.Level;
......@@ -26,7 +25,6 @@ import org.b3log.latke.mail.MailService.Message;
import org.b3log.latke.mail.MailServiceFactory;
import org.b3log.latke.repository.Query;
import org.b3log.latke.repository.Repositories;
import org.b3log.latke.repository.Repository;
import org.b3log.latke.repository.Transaction;
import org.b3log.latke.repository.annotation.Transactional;
import org.b3log.latke.servlet.HTTPRequestContext;
......@@ -41,7 +39,6 @@ import org.b3log.solo.model.Tag;
import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.TagArticleRepository;
import org.b3log.solo.repository.TagRepository;
import org.b3log.solo.repository.impl.*;
import org.b3log.solo.service.PreferenceMgmtService;
import org.b3log.solo.service.PreferenceQueryService;
import org.b3log.solo.service.StatisticMgmtService;
......@@ -50,20 +47,17 @@ import org.b3log.solo.util.Mails;
import org.json.JSONArray;
import org.json.JSONObject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
/**
* Provides patches on some special issues.
* <p>
* See AuthFilter filter configurations in web.xml for authentication.</p>
* See AuthFilter filter configurations in web.xml for authentication.
* </p>
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.2.0.13, Sep 6, 2017
* @version 1.2.0.14, Mar 11, 2018
* @since 0.3.1
*/
@RequestProcessor
......@@ -137,14 +131,11 @@ public class RepairProcessor {
LOGGER.log(Level.INFO, "Processes remove unused article properties");
final TextHTMLRenderer renderer = new TextHTMLRenderer();
context.setRenderer(renderer);
Transaction transaction = null;
try {
final JSONArray articles = articleRepository.get(new Query()).getJSONArray(Keys.RESULTS);
if (articles.length() <= 0) {
renderer.setContent("No unused article properties");
return;
......@@ -153,13 +144,11 @@ public class RepairProcessor {
transaction = articleRepository.beginTransaction();
final Set<String> keyNames = Repositories.getKeyNames(Article.ARTICLE);
for (int i = 0; i < articles.length(); i++) {
final JSONObject article = articles.getJSONObject(i);
final JSONArray names = article.names();
final Set<String> nameSet = CollectionUtils.jsonArrayToSet(names);
if (nameSet.removeAll(keyNames)) {
for (final String unusedName : nameSet) {
article.remove(unusedName);
......@@ -197,7 +186,6 @@ public class RepairProcessor {
final String originalSigns = preference.getString(Option.ID_C_SIGNS);
preference.put(Option.ID_C_SIGNS, Option.DefaultPreference.DEFAULT_SIGNS);
preferenceMgmtService.updatePreference(preference);
renderer.setContent("Restores signs succeeded.");
......@@ -230,7 +218,6 @@ public class RepairProcessor {
@Transactional
public void repairTagArticleCounter(final HTTPRequestContext context) {
final TextHTMLRenderer renderer = new TextHTMLRenderer();
context.setRenderer(renderer);
try {
......@@ -249,7 +236,6 @@ public class RepairProcessor {
final JSONObject tagArticle = tagArticles.getJSONObject(i);
final String articleId = tagArticle.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID);
final JSONObject article = articleRepository.get(articleId);
if (null == article) {
tagArticleRepository.remove(tagArticle.optString(Keys.OBJECT_ID));
......@@ -270,143 +256,10 @@ public class RepairProcessor {
tag.getString(Tag.TAG_TITLE), tagRefCnt, publishedTagRefCnt);
}
renderer.setContent("Repair sucessfully!");
renderer.setContent("Repair successfully!");
} catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
renderer.setContent("Repairs failed, error msg[" + e.getMessage() + "]");
}
}
/**
* Shows remove all data page.
*
* @param context the specified context
* @param request the specified HTTP servlet request
*/
@RequestProcessing(value = "/rm-all-data.do", method = HTTPRequestMethod.GET)
public void removeAllDataGET(final HTTPRequestContext context, final HttpServletRequest request) {
final TextHTMLRenderer renderer = new TextHTMLRenderer();
context.setRenderer(renderer);
try {
final StringBuilder htmlBuilder = new StringBuilder();
htmlBuilder.append("<html><head><title>WARNING!</title>");
htmlBuilder.append("<script type='text/javascript'");
htmlBuilder.append("src='").append(Latkes.getStaticServer()).append("/js/lib/jquery/jquery.min.js'");
htmlBuilder.append("></script></head><body>");
htmlBuilder.append("<button id='ok' onclick='removeData()'>");
htmlBuilder.append("Continue to delete ALL DATA</button></body>");
htmlBuilder.append("<script type='text/javascript'>");
htmlBuilder.append("function removeData() {");
htmlBuilder.append("$.ajax({type: 'POST',url:'").append(Latkes.getContextPath()).append("/rm-all-data.do',");
htmlBuilder.append("dataType: 'text/html',success: function(result){");
htmlBuilder.append("$('html').html(result);}});}</script></html>");
renderer.setContent(htmlBuilder.toString());
} catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
try {
context.getResponse().sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
} catch (final IOException ex) {
throw new RuntimeException(ex);
}
}
}
/**
* Removes all data.
*
* @param context the specified context
*/
@RequestProcessing(value = "/rm-all-data.do", method = HTTPRequestMethod.POST)
public void removeAllDataPOST(final HTTPRequestContext context) {
LOGGER.info("Removing all data....");
boolean succeed = false;
try {
remove(beanManager.getReference(ArchiveDateArticleRepositoryImpl.class));
remove(beanManager.getReference(ArchiveDateRepositoryImpl.class));
remove(beanManager.getReference(ArticleRepositoryImpl.class));
remove(beanManager.getReference(CommentRepositoryImpl.class));
remove(beanManager.getReference(LinkRepositoryImpl.class));
remove(beanManager.getReference(OptionRepositoryImpl.class));
remove(beanManager.getReference(PageRepositoryImpl.class));
remove(beanManager.getReference(PluginRepositoryImpl.class));
remove(beanManager.getReference(TagArticleRepositoryImpl.class));
remove(beanManager.getReference(TagRepositoryImpl.class));
remove(beanManager.getReference(UserRepositoryImpl.class));
succeed = true;
} catch (final Exception e) {
LOGGER.log(Level.WARN, "Removed partial data only", e);
}
final StringBuilder htmlBuilder = new StringBuilder();
htmlBuilder.append("<html><head><title>Result</title></head><body>");
try {
final TextHTMLRenderer renderer = new TextHTMLRenderer();
context.setRenderer(renderer);
if (succeed) {
htmlBuilder.append("Removed all data!");
} else {
htmlBuilder.append("Refresh this page and run this remover again.");
}
htmlBuilder.append("</body></html>");
renderer.setContent(htmlBuilder.toString());
} catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
try {
context.getResponse().sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
} catch (final IOException ex) {
throw new RuntimeException(ex);
}
}
LOGGER.info("Removed all data....");
}
/**
* Removes data in the specified repository.
*
* @param repository the specified repository
* @throws ExecutionException execution exception
* @throws InterruptedException interrupted exception
*/
private void remove(final Repository repository) throws ExecutionException, InterruptedException {
final long startTime = System.currentTimeMillis();
final long step = 20000;
final Transaction transaction = repository.beginTransaction();
try {
final JSONObject result = repository.get(new Query());
final JSONArray array = result.getJSONArray(Keys.RESULTS);
for (int i = 0; i < array.length(); i++) {
final JSONObject object = array.getJSONObject(i);
repository.remove(object.getString(Keys.OBJECT_ID));
if (System.currentTimeMillis() >= startTime + step) {
break;
}
}
transaction.commit();
} catch (final Exception e) {
if (transaction.isActive()) {
transaction.rollback();
}
LOGGER.log(Level.ERROR, "Removes all data in repository[name=" + repository.getName() + "] failed", e);
}
}
}
......@@ -15,7 +15,6 @@
*/
package org.b3log.solo.service;
import org.b3log.latke.Latkes;
import org.b3log.latke.ioc.inject.Inject;
import org.b3log.latke.logging.Level;
......@@ -29,12 +28,11 @@ import org.b3log.solo.repository.PageRepository;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Permalink query service.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.2, Mar 4, 2014
* @version 1.0.0.3, Mar 11, 2018
* @since 0.6.1
*/
@Service
......@@ -60,20 +58,19 @@ public class PermalinkQueryService {
/**
* Reserved permalinks.
*/
public static final String[] RESERVED_LINKS = new String[] {
"/", "/article", "/tags.html", "/tags", "/page", "/blog-articles-feed.do", "/tag-articles-feed.do", "/blog-articles-rss.do",
"/tag-articles-rss.do", "/get-random-articles.do", "/article-random-double-gen.do", "/captcha.do", "/kill-browser",
"/add-article-comment.do", "/add-article-from-symphony-comment.do", "/add-page-comment.do", "/get-article-content", "/sitemap.xml",
"/login", "/logout", "/forgot", "/get-article-content", "/admin-index.do", "/admin-article.do", "/admin-article-list.do",
"/admin-link-list.do", "/admin-preference.do", "/admin-file-list.do", "/admin-page-list.do", "/admin-others.do",
"/admin-draft-list.do", "/admin-user-list.do", "/admin-plugin-list.do", "/admin-main.do", "/admin-about.do", "/admin-label",
"/admin-about.do", "/rm-all-data.do", "/init", "/register.html"
public static final String[] RESERVED_LINKS = new String[]{
"/", "/article", "/tags.html", "/tags", "/page", "/blog-articles-feed.do", "/tag-articles-feed.do", "/blog-articles-rss.do",
"/tag-articles-rss.do", "/get-random-articles.do", "/article-random-double-gen.do", "/captcha.do", "/kill-browser",
"/add-article-comment.do", "/add-article-from-symphony-comment.do", "/add-page-comment.do", "/get-article-content", "/sitemap.xml",
"/login", "/logout", "/forgot", "/get-article-content", "/admin-index.do", "/admin-article.do", "/admin-article-list.do",
"/admin-link-list.do", "/admin-preference.do", "/admin-file-list.do", "/admin-page-list.do", "/admin-others.do",
"/admin-draft-list.do", "/admin-user-list.do", "/admin-plugin-list.do", "/admin-main.do", "/admin-about.do", "/admin-label",
"/admin-about.do", "/init", "/register.html"
};
/**
* Checks whether the specified article permalink matches the system generated format
* pattern ("/articles/yyyy/MM/dd/${articleId}.html").
*
* Checks whether the specified article permalink matches the system generated format pattern ("/articles/yyyy/MM/dd/${articleId}.html").
*
* @param permalink the specified permalink
* @return {@code true} if matches, returns {@code false} otherwise
*/
......@@ -86,7 +83,7 @@ public class PermalinkQueryService {
/**
* Checks whether the specified page permalink matches the system generated format pattern ("/pages/${pageId}.html").
*
*
* @param permalink the specified permalink
* @return {@code true} if matches, returns {@code false} otherwise
*/
......@@ -98,11 +95,11 @@ public class PermalinkQueryService {
}
/**
* Checks whether the specified permalink is a {@link #invalidArticlePermalinkFormat(java.lang.String) invalid article
* Checks whether the specified permalink is a {@link #invalidArticlePermalinkFormat(java.lang.String) invalid article
* permalink format} and {@link #invalidPagePermalinkFormat(java.lang.String) invalid page permalink format}.
*
*
* @param permalink the specified permalink
* @return {@code true} if invalid, returns {@code false} otherwise
* @return {@code true} if invalid, returns {@code false} otherwise
*/
public static boolean invalidPermalinkFormat(final String permalink) {
return invalidArticlePermalinkFormat(permalink) && invalidPagePermalinkFormat(permalink);
......@@ -110,7 +107,7 @@ public class PermalinkQueryService {
/**
* Checks whether the specified article permalink is invalid on format.
*
*
* @param permalink the specified article permalink
* @return {@code true} if invalid, returns {@code false} otherwise
*/
......@@ -128,7 +125,7 @@ public class PermalinkQueryService {
/**
* Checks whether the specified page permalink is invalid on format.
*
*
* @param permalink the specified page permalink
* @return {@code true} if invalid, returns {@code false} otherwise
*/
......@@ -146,7 +143,7 @@ public class PermalinkQueryService {
/**
* Checks whether the specified user-defined permalink is invalid on format.
*
*
* @param permalink the specified user-defined permalink
* @return {@code true} if invalid, returns {@code false} otherwise
*/
......@@ -181,12 +178,11 @@ public class PermalinkQueryService {
/**
* Determines whether the specified request URI is a reserved link.
*
* <p>
* A URI starts with one of {@link PermalinkQueryService#RESERVED_LINKS reserved links}
* will be treated as reserved link.
* </p>
*
*
* @param requestURI the specified request URI
* @return {@code true} if it is a reserved link, returns {@code false} otherwise
*/
......@@ -212,7 +208,7 @@ public class PermalinkQueryService {
public boolean exist(final String permalink) {
try {
return isReservedLink(permalink) || null != articleRepository.getByPermalink(permalink)
|| null != pageRepository.getByPermalink(permalink) || permalink.endsWith(".ftl");
|| null != pageRepository.getByPermalink(permalink) || permalink.endsWith(".ftl");
} catch (final RepositoryException e) {
LOGGER.log(Level.ERROR, "Determines whether the permalink[" + permalink + "] exists failed, returns true", e);
......@@ -222,7 +218,7 @@ public class PermalinkQueryService {
/**
* Sets the article repository with the specified article repository.
*
*
* @param articleRepository the specified article repository
*/
public void setArticleRepository(final ArticleRepository articleRepository) {
......@@ -231,7 +227,7 @@ public class PermalinkQueryService {
/**
* Set the page repository with the specified page repository.
*
*
* @param pageRepository the specified page repository
*/
public void setPageRepository(final PageRepository pageRepository) {
......
......@@ -18,7 +18,7 @@
-->
<!--
Description: Solo web deployment descriptor.
Version: 1.0.5.2, Oct 21, 2017
Version: 1.0.5.3, Mar 11, 2018
Author: Liang Ding
-->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
......@@ -63,7 +63,6 @@
<url-pattern>/admin-user-list.do</url-pattern>
<url-pattern>/admin-plugin-list.do</url-pattern>
<url-pattern>/admin-about.do</url-pattern>
<url-pattern>/rm-all-data.do</url-pattern>
<url-pattern>/fix/*</url-pattern>
</filter-mapping>
<filter>
......
......@@ -17,15 +17,16 @@
-->
<!--
Description: Solo web deployment descriptor.
Version: 1.0.5.1, Sep 27, 2013
Description: Solo web deployment descriptor for testing.
Version: 1.0.5.2, Mar 11, 2018
Author: Liang Ding
-->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<listener>
<listener-class>org.b3log.solo.SoloServletListener</listener-class>
</listener>
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>org.b3log.latke.servlet.filter.EncodingFilter</filter-class>
......@@ -42,7 +43,7 @@
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>org.b3log.solo.filter.AuthFilter</filter-class>
......@@ -62,7 +63,6 @@
<url-pattern>/admin-user-list.do</url-pattern>
<url-pattern>/admin-plugin-list.do</url-pattern>
<url-pattern>/admin-about.do</url-pattern>
<url-pattern>/rm-all-data.do</url-pattern>
<url-pattern>/fix/*</url-pattern>
</filter-mapping>
<filter>
......@@ -81,13 +81,13 @@
<filter-name>InitCheckFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>
5
</session-timeout>
</session-config>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.b3log.latke.servlet.DispatcherServlet</servlet-class>
......@@ -97,7 +97,7 @@
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Error Pages -->
<error-page>
<error-code>404</error-code>
......
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