Commit 4af1a1bb authored by Liang Ding's avatar Liang Ding

c

parent 2afd5b47
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.processor; package org.b3log.solo.processor;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringEscapeUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.annotation.RequestProcessing; import org.b3log.latke.annotation.RequestProcessing;
import org.b3log.latke.annotation.RequestProcessor; import org.b3log.latke.annotation.RequestProcessor;
import org.b3log.latke.model.User; import org.b3log.latke.model.User;
import org.b3log.latke.repository.FilterOperator; import org.b3log.latke.repository.FilterOperator;
import org.b3log.latke.repository.Query; import org.b3log.latke.repository.PropertyFilter;
import org.b3log.latke.repository.SortDirection; import org.b3log.latke.repository.Query;
import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.repository.SortDirection;
import org.b3log.latke.servlet.HTTPRequestMethod; import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.renderer.AtomRenderer; import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.renderer.RssRenderer; import org.b3log.latke.servlet.renderer.AtomRenderer;
import org.b3log.latke.util.Locales; import org.b3log.latke.servlet.renderer.RssRenderer;
import org.b3log.latke.util.Strings; import org.b3log.latke.util.Locales;
import org.b3log.solo.SoloServletListener; import org.b3log.latke.util.Strings;
import org.b3log.solo.model.Article; import org.b3log.solo.SoloServletListener;
import org.b3log.solo.model.Preference; import org.b3log.solo.model.Article;
import org.b3log.solo.model.Tag; import org.b3log.solo.model.Preference;
import org.b3log.solo.model.feed.atom.Category; import org.b3log.solo.model.Tag;
import org.b3log.solo.model.feed.atom.Entry; import org.b3log.solo.model.feed.atom.Category;
import org.b3log.solo.model.feed.atom.Feed; import org.b3log.solo.model.feed.atom.Entry;
import org.b3log.solo.model.feed.rss.Channel; import org.b3log.solo.model.feed.atom.Feed;
import org.b3log.solo.model.feed.rss.Item; import org.b3log.solo.model.feed.rss.Channel;
import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.model.feed.rss.Item;
import org.b3log.solo.repository.TagArticleRepository; import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.TagRepository; import org.b3log.solo.repository.TagArticleRepository;
import org.b3log.solo.repository.impl.ArticleRepositoryImpl; import org.b3log.solo.repository.TagRepository;
import org.b3log.solo.repository.impl.TagArticleRepositoryImpl; import org.b3log.solo.repository.impl.ArticleRepositoryImpl;
import org.b3log.solo.repository.impl.TagRepositoryImpl; import org.b3log.solo.repository.impl.TagArticleRepositoryImpl;
import org.b3log.solo.service.PreferenceQueryService; import org.b3log.solo.repository.impl.TagRepositoryImpl;
import org.b3log.solo.util.Articles; import org.b3log.solo.service.PreferenceQueryService;
import org.b3log.solo.util.TimeZones; import org.b3log.solo.util.Articles;
import org.b3log.solo.util.Users; import org.b3log.solo.util.TimeZones;
import org.json.JSONArray; import org.b3log.solo.util.Users;
import org.json.JSONObject; import org.json.JSONArray;
import org.json.JSONObject;
/**
* Feed (Atom/RSS) processor. /**
* * Feed (Atom/RSS) processor.
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> *
* @version 1.1.0.0, May 10, 2012 * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @since 0.3.1 * @version 1.1.0.0, May 10, 2012
*/ * @since 0.3.1
@RequestProcessor */
public final class FeedProcessor { @RequestProcessor
public final class FeedProcessor {
/**
* Logger. /**
*/ * Logger.
private static final Logger LOGGER = Logger.getLogger(FeedProcessor.class.getName()); */
/** private static final Logger LOGGER = Logger.getLogger(FeedProcessor.class.getName());
* Article repository. /**
*/ * Article repository.
private ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance(); */
/** private ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance();
* Preference query service. /**
*/ * Preference query service.
private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance(); */
/** private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance();
* Count of output entry. /**
*/ * Count of output entry.
public static final int ENTRY_OUTPUT_CNT = 10; */
/** public static final int ENTRY_OUTPUT_CNT = 10;
* Article utilities. /**
*/ * Article utilities.
private Articles articleUtils = Articles.getInstance(); */
/** private Articles articleUtils = Articles.getInstance();
* Tag repository. /**
*/ * Tag repository.
private TagRepository tagRepository = TagRepositoryImpl.getInstance(); */
/** private TagRepository tagRepository = TagRepositoryImpl.getInstance();
* Tag-Article repository. /**
*/ * Tag-Article repository.
private TagArticleRepository tagArticleRepository = TagArticleRepositoryImpl.getInstance(); */
private TagArticleRepository tagArticleRepository = TagArticleRepositoryImpl.getInstance();
/**
* Blog articles Atom output. /**
* * Blog articles Atom output.
* @param context the specified context *
*/ * @param context the specified context
@RequestProcessing(value = {"/blog-articles-feed.do"}, method = {HTTPRequestMethod.GET, HTTPRequestMethod.HEAD}) */
public void blogArticlesAtom(final HTTPRequestContext context) { @RequestProcessing(value = {"/blog-articles-feed.do"}, method = {HTTPRequestMethod.GET, HTTPRequestMethod.HEAD})
final AtomRenderer renderer = new AtomRenderer(); public void blogArticlesAtom(final HTTPRequestContext context) {
context.setRenderer(renderer); final AtomRenderer renderer = new AtomRenderer();
context.setRenderer(renderer);
final Feed feed = new Feed();
try { final Feed feed = new Feed();
final JSONObject preference = preferenceQueryService.getPreference(); try {
final JSONObject preference = preferenceQueryService.getPreference();
final String blogTitle = preference.getString(Preference.BLOG_TITLE);
final String blogSubtitle = preference.getString(Preference.BLOG_SUBTITLE); final String blogTitle = preference.getString(Preference.BLOG_TITLE);
final String blogHost = preference.getString(Preference.BLOG_HOST); final String blogSubtitle = preference.getString(Preference.BLOG_SUBTITLE);
final String blogHost = preference.getString(Preference.BLOG_HOST);
feed.setTitle(StringEscapeUtils.escapeXml(blogTitle));
feed.setSubtitle(StringEscapeUtils.escapeXml(blogSubtitle)); feed.setTitle(StringEscapeUtils.escapeXml(blogTitle));
feed.setUpdated(TimeZones.getTime(preference.getString(Preference.TIME_ZONE_ID))); feed.setSubtitle(StringEscapeUtils.escapeXml(blogSubtitle));
feed.setAuthor(StringEscapeUtils.escapeXml(blogTitle)); feed.setUpdated(TimeZones.getTime(preference.getString(Preference.TIME_ZONE_ID)));
feed.setLink("http://" + blogHost + "/blog-articles-feed.do"); feed.setAuthor(StringEscapeUtils.escapeXml(blogTitle));
feed.setId("http://" + blogHost + "/"); feed.setLink("http://" + blogHost + "/blog-articles-feed.do");
feed.setId("http://" + blogHost + "/");
final Query query = new Query().setCurrentPageNum(1).
setPageSize(ENTRY_OUTPUT_CNT). final Query query = new Query().setCurrentPageNum(1).
addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true). setPageSize(ENTRY_OUTPUT_CNT).
addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING). setFilter(new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true)).
setPageCount(1); addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING).
setPageCount(1);
final boolean hasMultipleUsers = Users.getInstance().hasMultipleUsers();
String authorName = ""; final boolean hasMultipleUsers = Users.getInstance().hasMultipleUsers();
String authorName = "";
final JSONObject articleResult = articleRepository.get(query);
final JSONArray articles = articleResult.getJSONArray(Keys.RESULTS); final JSONObject articleResult = articleRepository.get(query);
final JSONArray articles = articleResult.getJSONArray(Keys.RESULTS);
if (!hasMultipleUsers && 0 != articles.length()) {
authorName = articleUtils.getAuthor(articles.getJSONObject(0)).getString(User.USER_NAME); if (!hasMultipleUsers && 0 != articles.length()) {
} authorName = articleUtils.getAuthor(articles.getJSONObject(0)).getString(User.USER_NAME);
}
final boolean isFullContent = "fullContent".equals(preference.getString(Preference.FEED_OUTPUT_MODE));
final boolean isFullContent = "fullContent".equals(preference.getString(Preference.FEED_OUTPUT_MODE));
for (int i = 0; i < articles.length(); i++) {
final JSONObject article = articles.getJSONObject(i); for (int i = 0; i < articles.length(); i++) {
final Entry entry = new Entry(); final JSONObject article = articles.getJSONObject(i);
feed.addEntry(entry); final Entry entry = new Entry();
final String title = StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_TITLE)); feed.addEntry(entry);
entry.setTitle(title); final String title = StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_TITLE));
final String summary = isFullContent ? StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_CONTENT)) entry.setTitle(title);
: StringEscapeUtils.escapeXml(article.optString(Article.ARTICLE_ABSTRACT)); final String summary = isFullContent ? StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_CONTENT))
entry.setSummary(summary); : StringEscapeUtils.escapeXml(article.optString(Article.ARTICLE_ABSTRACT));
final Date updated = (Date) article.get(Article.ARTICLE_UPDATE_DATE); entry.setSummary(summary);
entry.setUpdated(updated); final Date updated = (Date) article.get(Article.ARTICLE_UPDATE_DATE);
entry.setUpdated(updated);
final String link = "http://" + blogHost + article.getString(Article.ARTICLE_PERMALINK);
entry.setLink(link); final String link = "http://" + blogHost + article.getString(Article.ARTICLE_PERMALINK);
entry.setId(link); entry.setLink(link);
entry.setId(link);
if (hasMultipleUsers) {
authorName = StringEscapeUtils.escapeXml(articleUtils.getAuthor(article).getString(User.USER_NAME)); if (hasMultipleUsers) {
} authorName = StringEscapeUtils.escapeXml(articleUtils.getAuthor(article).getString(User.USER_NAME));
entry.setAuthor(authorName); }
entry.setAuthor(authorName);
final String tagsString = article.getString(Article.ARTICLE_TAGS_REF);
final String[] tagStrings = tagsString.split(","); final String tagsString = article.getString(Article.ARTICLE_TAGS_REF);
for (int j = 0; j < tagStrings.length; j++) { final String[] tagStrings = tagsString.split(",");
final Category catetory = new Category(); for (int j = 0; j < tagStrings.length; j++) {
entry.addCatetory(catetory); final Category catetory = new Category();
final String tag = tagStrings[j]; entry.addCatetory(catetory);
catetory.setTerm(tag); final String tag = tagStrings[j];
} catetory.setTerm(tag);
} }
}
renderer.setContent(feed.toString());
} catch (final Exception e) { renderer.setContent(feed.toString());
LOGGER.log(Level.SEVERE, "Get blog article feed error", e); } catch (final Exception e) {
LOGGER.log(Level.SEVERE, "Get blog article feed error", e);
try {
context.getResponse().sendError( try {
HttpServletResponse.SC_SERVICE_UNAVAILABLE); context.getResponse().sendError(
} catch (final IOException ex) { HttpServletResponse.SC_SERVICE_UNAVAILABLE);
throw new RuntimeException(ex); } catch (final IOException ex) {
} throw new RuntimeException(ex);
} }
} }
}
/**
* Tag articles Atom output. /**
* * Tag articles Atom output.
* @param context the specified context *
* @throws IOException io exception * @param context the specified context
*/ * @throws IOException io exception
@RequestProcessing(value = {"/tag-articles-feed.do"}, method = {HTTPRequestMethod.GET, HTTPRequestMethod.HEAD}) */
public void tagArticlesAtom(final HTTPRequestContext context) throws IOException { @RequestProcessing(value = {"/tag-articles-feed.do"}, method = {HTTPRequestMethod.GET, HTTPRequestMethod.HEAD})
final AtomRenderer renderer = new AtomRenderer(); public void tagArticlesAtom(final HTTPRequestContext context) throws IOException {
context.setRenderer(renderer); final AtomRenderer renderer = new AtomRenderer();
context.setRenderer(renderer);
final HttpServletRequest request = context.getRequest();
final HttpServletResponse response = context.getResponse(); final HttpServletRequest request = context.getRequest();
final HttpServletResponse response = context.getResponse();
final String queryString = request.getQueryString();
final String queryString = request.getQueryString();
if (Strings.isEmptyOrNull(queryString)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST); if (Strings.isEmptyOrNull(queryString)) {
return; response.sendError(HttpServletResponse.SC_BAD_REQUEST);
} return;
}
final String oIdMap = queryString.split("&")[0];
final String tagId = oIdMap.split("=")[1]; final String oIdMap = queryString.split("&")[0];
final String tagId = oIdMap.split("=")[1];
final Feed feed = new Feed();
try { final Feed feed = new Feed();
final String tagTitle = tagRepository.get(tagId).getString(Tag.TAG_TITLE); try {
final String tagTitle = tagRepository.get(tagId).getString(Tag.TAG_TITLE);
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) { final JSONObject preference = preferenceQueryService.getPreference();
response.sendError(HttpServletResponse.SC_NOT_FOUND); if (null == preference) {
return; response.sendError(HttpServletResponse.SC_NOT_FOUND);
} return;
}
final String blogTitle = preference.getString(Preference.BLOG_TITLE);
final String blogSubtitle = preference.getString(Preference.BLOG_SUBTITLE) + ", " + tagTitle; final String blogTitle = preference.getString(Preference.BLOG_TITLE);
final String blogHost = preference.getString(Preference.BLOG_HOST); final String blogSubtitle = preference.getString(Preference.BLOG_SUBTITLE) + ", " + tagTitle;
final String blogHost = preference.getString(Preference.BLOG_HOST);
feed.setTitle(StringEscapeUtils.escapeXml(blogTitle));
feed.setSubtitle(StringEscapeUtils.escapeXml(blogSubtitle)); feed.setTitle(StringEscapeUtils.escapeXml(blogTitle));
feed.setUpdated(TimeZones.getTime(preference.getString(Preference.TIME_ZONE_ID))); feed.setSubtitle(StringEscapeUtils.escapeXml(blogSubtitle));
feed.setAuthor(StringEscapeUtils.escapeXml(blogTitle)); feed.setUpdated(TimeZones.getTime(preference.getString(Preference.TIME_ZONE_ID)));
feed.setLink("http://" + blogHost + "/tag-articles-feed.do"); feed.setAuthor(StringEscapeUtils.escapeXml(blogTitle));
feed.setId("http://" + blogHost + "/"); feed.setLink("http://" + blogHost + "/tag-articles-feed.do");
feed.setId("http://" + blogHost + "/");
final JSONObject tagArticleResult = tagArticleRepository.getByTagId(tagId, 1, ENTRY_OUTPUT_CNT);
final JSONArray tagArticleRelations = tagArticleResult.getJSONArray(Keys.RESULTS); final JSONObject tagArticleResult = tagArticleRepository.getByTagId(tagId, 1, ENTRY_OUTPUT_CNT);
if (0 == tagArticleRelations.length()) { final JSONArray tagArticleRelations = tagArticleResult.getJSONArray(Keys.RESULTS);
response.sendError(HttpServletResponse.SC_NOT_FOUND); if (0 == tagArticleRelations.length()) {
return; response.sendError(HttpServletResponse.SC_NOT_FOUND);
} return;
}
final List<JSONObject> articles = new ArrayList<JSONObject>();
for (int i = 0; i < tagArticleRelations.length(); i++) { final List<JSONObject> articles = new ArrayList<JSONObject>();
final JSONObject tagArticleRelation = tagArticleRelations.getJSONObject(i); for (int i = 0; i < tagArticleRelations.length(); i++) {
final String articleId = tagArticleRelation.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID); final JSONObject tagArticleRelation = tagArticleRelations.getJSONObject(i);
final JSONObject article = articleRepository.get(articleId); final String articleId = tagArticleRelation.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID);
if (article.getBoolean(Article.ARTICLE_IS_PUBLISHED)) { // Skips the unpublished article final JSONObject article = articleRepository.get(articleId);
articles.add(article); if (article.getBoolean(Article.ARTICLE_IS_PUBLISHED)) { // Skips the unpublished article
} articles.add(article);
} }
}
final boolean hasMultipleUsers = Users.getInstance().hasMultipleUsers();
String authorName = ""; final boolean hasMultipleUsers = Users.getInstance().hasMultipleUsers();
String authorName = "";
if (!hasMultipleUsers && !articles.isEmpty()) {
authorName = articleUtils.getAuthor(articles.get(0)).getString(User.USER_NAME); if (!hasMultipleUsers && !articles.isEmpty()) {
} authorName = articleUtils.getAuthor(articles.get(0)).getString(User.USER_NAME);
}
final boolean isFullContent = "fullContent".equals(preference.getString(Preference.FEED_OUTPUT_MODE));
final boolean isFullContent = "fullContent".equals(preference.getString(Preference.FEED_OUTPUT_MODE));
for (int i = 0; i < articles.size(); i++) {
final JSONObject article = articles.get(i); for (int i = 0; i < articles.size(); i++) {
final Entry entry = new Entry(); final JSONObject article = articles.get(i);
feed.addEntry(entry); final Entry entry = new Entry();
final String title = StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_TITLE)); feed.addEntry(entry);
entry.setTitle(title); final String title = StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_TITLE));
final String summary = isFullContent ? StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_CONTENT)) entry.setTitle(title);
: StringEscapeUtils.escapeXml(article.optString(Article.ARTICLE_ABSTRACT)); final String summary = isFullContent ? StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_CONTENT))
entry.setSummary(summary); : StringEscapeUtils.escapeXml(article.optString(Article.ARTICLE_ABSTRACT));
final Date updated = (Date) article.get(Article.ARTICLE_UPDATE_DATE); entry.setSummary(summary);
entry.setUpdated(updated); final Date updated = (Date) article.get(Article.ARTICLE_UPDATE_DATE);
final String link = "http://" + blogHost + article.getString(Article.ARTICLE_PERMALINK); entry.setUpdated(updated);
entry.setLink(link); final String link = "http://" + blogHost + article.getString(Article.ARTICLE_PERMALINK);
entry.setId(link); entry.setLink(link);
entry.setId(link);
if (hasMultipleUsers) {
authorName = StringEscapeUtils.escapeXml(articleUtils.getAuthor(article).getString(User.USER_NAME)); if (hasMultipleUsers) {
} authorName = StringEscapeUtils.escapeXml(articleUtils.getAuthor(article).getString(User.USER_NAME));
}
entry.setAuthor(authorName);
entry.setAuthor(authorName);
final String tagsString = article.getString(Article.ARTICLE_TAGS_REF);
final String[] tagStrings = tagsString.split(","); final String tagsString = article.getString(Article.ARTICLE_TAGS_REF);
for (int j = 0; j < tagStrings.length; j++) { final String[] tagStrings = tagsString.split(",");
final Category catetory = new Category(); for (int j = 0; j < tagStrings.length; j++) {
entry.addCatetory(catetory); final Category catetory = new Category();
final String tag = tagStrings[j]; entry.addCatetory(catetory);
catetory.setTerm(tag); final String tag = tagStrings[j];
} catetory.setTerm(tag);
} }
}
renderer.setContent(feed.toString());
} catch (final Exception e) { renderer.setContent(feed.toString());
LOGGER.log(Level.SEVERE, "Get tag article feed error", e); } catch (final Exception e) {
LOGGER.log(Level.SEVERE, "Get tag article feed error", e);
try {
context.getResponse().sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); try {
} catch (final IOException ex) { context.getResponse().sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
throw new RuntimeException(ex); } catch (final IOException ex) {
} throw new RuntimeException(ex);
} }
} }
}
/**
* Blog articles RSS output. /**
* * Blog articles RSS output.
* @param context the specified context *
*/ * @param context the specified context
@RequestProcessing(value = {"/blog-articles-rss.do"}, method = {HTTPRequestMethod.GET, HTTPRequestMethod.HEAD}) */
public void blogArticlesRSS(final HTTPRequestContext context) { @RequestProcessing(value = {"/blog-articles-rss.do"}, method = {HTTPRequestMethod.GET, HTTPRequestMethod.HEAD})
final HttpServletResponse response = context.getResponse(); public void blogArticlesRSS(final HTTPRequestContext context) {
final RssRenderer renderer = new RssRenderer(); final HttpServletResponse response = context.getResponse();
context.setRenderer(renderer); final RssRenderer renderer = new RssRenderer();
context.setRenderer(renderer);
final Channel channel = new Channel();
try { final Channel channel = new Channel();
final JSONObject preference = preferenceQueryService.getPreference(); try {
if (null == preference) { final JSONObject preference = preferenceQueryService.getPreference();
response.sendError(HttpServletResponse.SC_NOT_FOUND); if (null == preference) {
return; response.sendError(HttpServletResponse.SC_NOT_FOUND);
} return;
}
final String blogTitle = preference.getString(Preference.BLOG_TITLE);
final String blogSubtitle = preference.getString(Preference.BLOG_SUBTITLE); final String blogTitle = preference.getString(Preference.BLOG_TITLE);
final String blogHost = preference.getString(Preference.BLOG_HOST); final String blogSubtitle = preference.getString(Preference.BLOG_SUBTITLE);
final String blogHost = preference.getString(Preference.BLOG_HOST);
channel.setTitle(StringEscapeUtils.escapeXml(blogTitle));
channel.setLastBuildDate(TimeZones.getTime(preference.getString(Preference.TIME_ZONE_ID))); channel.setTitle(StringEscapeUtils.escapeXml(blogTitle));
channel.setLink("http://" + blogHost); channel.setLastBuildDate(TimeZones.getTime(preference.getString(Preference.TIME_ZONE_ID)));
channel.setAtomLink("http://" + blogHost + "/blog-articles-rss.do"); channel.setLink("http://" + blogHost);
channel.setGenerator("B3log Solo, ver " + SoloServletListener.VERSION); channel.setAtomLink("http://" + blogHost + "/blog-articles-rss.do");
final String localeString = preference.getString(Preference.LOCALE_STRING); channel.setGenerator("B3log Solo, ver " + SoloServletListener.VERSION);
final String country = Locales.getCountry(localeString).toLowerCase(); final String localeString = preference.getString(Preference.LOCALE_STRING);
final String language = Locales.getLanguage(localeString).toLowerCase(); final String country = Locales.getCountry(localeString).toLowerCase();
channel.setLanguage(language + '-' + country); final String language = Locales.getLanguage(localeString).toLowerCase();
channel.setDescription(blogSubtitle); channel.setLanguage(language + '-' + country);
channel.setDescription(blogSubtitle);
final Query query = new Query().setCurrentPageNum(1).
setPageSize(ENTRY_OUTPUT_CNT). final Query query = new Query().setCurrentPageNum(1).
addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true). setPageSize(ENTRY_OUTPUT_CNT).
addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING). setFilter(new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true)).
setPageCount(1); addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING).
setPageCount(1);
final JSONObject articleResult = articleRepository.get(query);
final JSONArray articles = articleResult.getJSONArray(Keys.RESULTS); final JSONObject articleResult = articleRepository.get(query);
final JSONArray articles = articleResult.getJSONArray(Keys.RESULTS);
final boolean hasMultipleUsers = Users.getInstance().hasMultipleUsers();
String authorName = ""; final boolean hasMultipleUsers = Users.getInstance().hasMultipleUsers();
String authorName = "";
if (!hasMultipleUsers && 0 != articles.length()) {
authorName = articleUtils.getAuthor(articles.getJSONObject(0)).getString(User.USER_NAME); if (!hasMultipleUsers && 0 != articles.length()) {
} authorName = articleUtils.getAuthor(articles.getJSONObject(0)).getString(User.USER_NAME);
}
final boolean isFullContent = "fullContent".equals(preference.getString(Preference.FEED_OUTPUT_MODE));
final boolean isFullContent = "fullContent".equals(preference.getString(Preference.FEED_OUTPUT_MODE));
for (int i = 0; i < articles.length(); i++) {
final JSONObject article = articles.getJSONObject(i); for (int i = 0; i < articles.length(); i++) {
final Item item = new Item(); final JSONObject article = articles.getJSONObject(i);
channel.addItem(item); final Item item = new Item();
final String title = StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_TITLE)); channel.addItem(item);
item.setTitle(title); final String title = StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_TITLE));
final String description = isFullContent ? StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_CONTENT)) item.setTitle(title);
: StringEscapeUtils.escapeXml(article.optString(Article.ARTICLE_ABSTRACT)); final String description = isFullContent ? StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_CONTENT))
item.setDescription(description); : StringEscapeUtils.escapeXml(article.optString(Article.ARTICLE_ABSTRACT));
final Date pubDate = (Date) article.get(Article.ARTICLE_UPDATE_DATE); item.setDescription(description);
item.setPubDate(pubDate); final Date pubDate = (Date) article.get(Article.ARTICLE_UPDATE_DATE);
final String link = "http://" + blogHost + article.getString(Article.ARTICLE_PERMALINK); item.setPubDate(pubDate);
item.setLink(link); final String link = "http://" + blogHost + article.getString(Article.ARTICLE_PERMALINK);
item.setGUID(link); item.setLink(link);
item.setGUID(link);
final String authorEmail = article.getString(Article.ARTICLE_AUTHOR_EMAIL);
if (hasMultipleUsers) { final String authorEmail = article.getString(Article.ARTICLE_AUTHOR_EMAIL);
authorName = StringEscapeUtils.escapeXml(articleUtils.getAuthor(article).getString(User.USER_NAME)); if (hasMultipleUsers) {
} authorName = StringEscapeUtils.escapeXml(articleUtils.getAuthor(article).getString(User.USER_NAME));
}
item.setAuthor(authorEmail + "(" + authorName + ")");
item.setAuthor(authorEmail + "(" + authorName + ")");
final String tagsString = article.getString(Article.ARTICLE_TAGS_REF);
final String[] tagStrings = tagsString.split(","); final String tagsString = article.getString(Article.ARTICLE_TAGS_REF);
for (int j = 0; j < tagStrings.length; j++) { final String[] tagStrings = tagsString.split(",");
final org.b3log.solo.model.feed.rss.Category catetory = new org.b3log.solo.model.feed.rss.Category(); for (int j = 0; j < tagStrings.length; j++) {
item.addCatetory(catetory); final org.b3log.solo.model.feed.rss.Category catetory = new org.b3log.solo.model.feed.rss.Category();
final String tag = tagStrings[j]; item.addCatetory(catetory);
catetory.setTerm(tag); final String tag = tagStrings[j];
} catetory.setTerm(tag);
} }
}
renderer.setContent(channel.toString());
} catch (final Exception e) { renderer.setContent(channel.toString());
LOGGER.log(Level.SEVERE, "Get blog article rss error", e); } catch (final Exception e) {
LOGGER.log(Level.SEVERE, "Get blog article rss error", e);
try {
context.getResponse().sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); try {
} catch (final IOException ex) { context.getResponse().sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
throw new RuntimeException(ex); } catch (final IOException ex) {
} throw new RuntimeException(ex);
} }
} }
}
/**
* Tag articles RSS output. /**
* * Tag articles RSS output.
* @param context the specified context *
* @throws IOException io exception * @param context the specified context
*/ * @throws IOException io exception
@RequestProcessing(value = {"/tag-articles-rss.do"}, method = {HTTPRequestMethod.GET, HTTPRequestMethod.HEAD}) */
public void tagArticlesRSS(final HTTPRequestContext context) throws IOException { @RequestProcessing(value = {"/tag-articles-rss.do"}, method = {HTTPRequestMethod.GET, HTTPRequestMethod.HEAD})
final HttpServletResponse response = context.getResponse(); public void tagArticlesRSS(final HTTPRequestContext context) throws IOException {
final HttpServletRequest request = context.getRequest(); final HttpServletResponse response = context.getResponse();
final HttpServletRequest request = context.getRequest();
final RssRenderer renderer = new RssRenderer();
context.setRenderer(renderer); final RssRenderer renderer = new RssRenderer();
context.setRenderer(renderer);
final String queryString = request.getQueryString();
if (Strings.isEmptyOrNull(queryString)) { final String queryString = request.getQueryString();
response.sendError(HttpServletResponse.SC_BAD_REQUEST); if (Strings.isEmptyOrNull(queryString)) {
return; response.sendError(HttpServletResponse.SC_BAD_REQUEST);
} return;
}
final String oIdMap = queryString.split("&")[0];
final String tagId = oIdMap.split("=")[1]; final String oIdMap = queryString.split("&")[0];
final String tagId = oIdMap.split("=")[1];
final Channel channel = new Channel();
try { final Channel channel = new Channel();
final String tagTitle = tagRepository.get(tagId).getString(Tag.TAG_TITLE); try {
final String tagTitle = tagRepository.get(tagId).getString(Tag.TAG_TITLE);
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) { final JSONObject preference = preferenceQueryService.getPreference();
response.sendError(HttpServletResponse.SC_NOT_FOUND); if (null == preference) {
return; response.sendError(HttpServletResponse.SC_NOT_FOUND);
} return;
}
final String blogTitle = preference.getString(Preference.BLOG_TITLE);
final String blogSubtitle = preference.getString(Preference.BLOG_SUBTITLE) + ", " + tagTitle; final String blogTitle = preference.getString(Preference.BLOG_TITLE);
final String blogHost = preference.getString(Preference.BLOG_HOST); final String blogSubtitle = preference.getString(Preference.BLOG_SUBTITLE) + ", " + tagTitle;
final String blogHost = preference.getString(Preference.BLOG_HOST);
channel.setTitle(StringEscapeUtils.escapeXml(blogTitle));
channel.setLastBuildDate(TimeZones.getTime(preference.getString(Preference.TIME_ZONE_ID))); channel.setTitle(StringEscapeUtils.escapeXml(blogTitle));
channel.setLink("http://" + blogHost); channel.setLastBuildDate(TimeZones.getTime(preference.getString(Preference.TIME_ZONE_ID)));
channel.setAtomLink("http://" + blogHost + "/tag-articles-rss.do"); channel.setLink("http://" + blogHost);
channel.setGenerator("B3log Solo, ver " + SoloServletListener.VERSION); channel.setAtomLink("http://" + blogHost + "/tag-articles-rss.do");
final String localeString = preference.getString(Preference.LOCALE_STRING); channel.setGenerator("B3log Solo, ver " + SoloServletListener.VERSION);
final String country = Locales.getCountry(localeString).toLowerCase(); final String localeString = preference.getString(Preference.LOCALE_STRING);
final String language = Locales.getLanguage(localeString).toLowerCase(); final String country = Locales.getCountry(localeString).toLowerCase();
channel.setLanguage(language + '-' + country); final String language = Locales.getLanguage(localeString).toLowerCase();
channel.setDescription(blogSubtitle); channel.setLanguage(language + '-' + country);
channel.setDescription(blogSubtitle);
final JSONObject tagArticleResult = tagArticleRepository.getByTagId(tagId, 1, ENTRY_OUTPUT_CNT);
final JSONArray tagArticleRelations = tagArticleResult.getJSONArray(Keys.RESULTS); final JSONObject tagArticleResult = tagArticleRepository.getByTagId(tagId, 1, ENTRY_OUTPUT_CNT);
if (0 == tagArticleRelations.length()) { final JSONArray tagArticleRelations = tagArticleResult.getJSONArray(Keys.RESULTS);
response.sendError(HttpServletResponse.SC_NOT_FOUND); if (0 == tagArticleRelations.length()) {
return; response.sendError(HttpServletResponse.SC_NOT_FOUND);
} return;
}
final List<JSONObject> articles = new ArrayList<JSONObject>();
for (int i = 0; i < tagArticleRelations.length(); i++) { final List<JSONObject> articles = new ArrayList<JSONObject>();
final JSONObject tagArticleRelation = tagArticleRelations.getJSONObject(i); for (int i = 0; i < tagArticleRelations.length(); i++) {
final String articleId = tagArticleRelation.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID); final JSONObject tagArticleRelation = tagArticleRelations.getJSONObject(i);
final JSONObject article = articleRepository.get(articleId); final String articleId = tagArticleRelation.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID);
if (article.getBoolean(Article.ARTICLE_IS_PUBLISHED)) { // Skips the unpublished article final JSONObject article = articleRepository.get(articleId);
articles.add(article); if (article.getBoolean(Article.ARTICLE_IS_PUBLISHED)) { // Skips the unpublished article
} articles.add(article);
} }
}
final boolean hasMultipleUsers = Users.getInstance().hasMultipleUsers();
String authorName = ""; final boolean hasMultipleUsers = Users.getInstance().hasMultipleUsers();
String authorName = "";
if (!hasMultipleUsers && !articles.isEmpty()) {
authorName = articleUtils.getAuthor(articles.get(0)).getString(User.USER_NAME); if (!hasMultipleUsers && !articles.isEmpty()) {
} authorName = articleUtils.getAuthor(articles.get(0)).getString(User.USER_NAME);
}
final boolean isFullContent = "fullContent".equals(preference.getString(Preference.FEED_OUTPUT_MODE));
final boolean isFullContent = "fullContent".equals(preference.getString(Preference.FEED_OUTPUT_MODE));
for (int i = 0; i < articles.size(); i++) {
final JSONObject article = articles.get(i); for (int i = 0; i < articles.size(); i++) {
final Item item = new Item(); final JSONObject article = articles.get(i);
channel.addItem(item); final Item item = new Item();
final String title = StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_TITLE)); channel.addItem(item);
item.setTitle(title); final String title = StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_TITLE));
final String description = isFullContent ? StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_CONTENT)) item.setTitle(title);
: StringEscapeUtils.escapeXml(article.optString(Article.ARTICLE_ABSTRACT)); final String description = isFullContent ? StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_CONTENT))
item.setDescription(description); : StringEscapeUtils.escapeXml(article.optString(Article.ARTICLE_ABSTRACT));
final Date pubDate = (Date) article.get(Article.ARTICLE_UPDATE_DATE); item.setDescription(description);
item.setPubDate(pubDate); final Date pubDate = (Date) article.get(Article.ARTICLE_UPDATE_DATE);
final String link = "http://" + blogHost + article.getString(Article.ARTICLE_PERMALINK); item.setPubDate(pubDate);
item.setLink(link); final String link = "http://" + blogHost + article.getString(Article.ARTICLE_PERMALINK);
item.setGUID(link); item.setLink(link);
item.setGUID(link);
final String authorEmail = article.getString(Article.ARTICLE_AUTHOR_EMAIL);
if (hasMultipleUsers) { final String authorEmail = article.getString(Article.ARTICLE_AUTHOR_EMAIL);
authorName = StringEscapeUtils.escapeXml(articleUtils.getAuthor(article).getString(User.USER_NAME)); if (hasMultipleUsers) {
} authorName = StringEscapeUtils.escapeXml(articleUtils.getAuthor(article).getString(User.USER_NAME));
}
item.setAuthor(authorEmail + "(" + authorName + ")");
item.setAuthor(authorEmail + "(" + authorName + ")");
final String tagsString = article.getString(Article.ARTICLE_TAGS_REF);
final String[] tagStrings = tagsString.split(","); final String tagsString = article.getString(Article.ARTICLE_TAGS_REF);
for (int j = 0; j < tagStrings.length; j++) { final String[] tagStrings = tagsString.split(",");
final org.b3log.solo.model.feed.rss.Category catetory = new org.b3log.solo.model.feed.rss.Category(); for (int j = 0; j < tagStrings.length; j++) {
item.addCatetory(catetory); final org.b3log.solo.model.feed.rss.Category catetory = new org.b3log.solo.model.feed.rss.Category();
final String tag = tagStrings[j]; item.addCatetory(catetory);
catetory.setTerm(tag); final String tag = tagStrings[j];
} catetory.setTerm(tag);
} }
}
renderer.setContent(channel.toString());
} catch (final Exception e) { renderer.setContent(channel.toString());
LOGGER.log(Level.SEVERE, "Get tag article rss error", e); } catch (final Exception e) {
LOGGER.log(Level.SEVERE, "Get tag article rss error", e);
try {
context.getResponse().sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); try {
} catch (final IOException ex) { context.getResponse().sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
throw new RuntimeException(ex); } catch (final IOException ex) {
} throw new RuntimeException(ex);
} }
} }
} }
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.processor; package org.b3log.solo.processor;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Date; import java.util.Date;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.time.DateFormatUtils; import org.apache.commons.lang.time.DateFormatUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.annotation.RequestProcessing; import org.b3log.latke.annotation.RequestProcessing;
import org.b3log.latke.annotation.RequestProcessor; import org.b3log.latke.annotation.RequestProcessor;
import org.b3log.latke.repository.FilterOperator; import org.b3log.latke.repository.FilterOperator;
import org.b3log.latke.repository.Query; import org.b3log.latke.repository.PropertyFilter;
import org.b3log.latke.repository.SortDirection; import org.b3log.latke.repository.Query;
import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.repository.SortDirection;
import org.b3log.latke.servlet.HTTPRequestMethod; import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.renderer.TextXMLRenderer; import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.solo.model.ArchiveDate; import org.b3log.latke.servlet.renderer.TextXMLRenderer;
import org.b3log.solo.model.Article; import org.b3log.solo.model.ArchiveDate;
import org.b3log.solo.model.Page; import org.b3log.solo.model.Article;
import org.b3log.solo.model.Preference; import org.b3log.solo.model.Page;
import org.b3log.solo.model.Tag; import org.b3log.solo.model.Preference;
import org.b3log.solo.model.sitemap.Sitemap; import org.b3log.solo.model.Tag;
import org.b3log.solo.model.sitemap.URL; import org.b3log.solo.model.sitemap.Sitemap;
import org.b3log.solo.repository.ArchiveDateRepository; import org.b3log.solo.model.sitemap.URL;
import org.b3log.solo.repository.PageRepository; import org.b3log.solo.repository.ArchiveDateRepository;
import org.b3log.solo.repository.TagRepository; import org.b3log.solo.repository.PageRepository;
import org.b3log.solo.repository.impl.ArchiveDateRepositoryImpl; import org.b3log.solo.repository.TagRepository;
import org.b3log.solo.repository.impl.ArticleRepositoryImpl; import org.b3log.solo.repository.impl.ArchiveDateRepositoryImpl;
import org.b3log.solo.repository.impl.PageRepositoryImpl; import org.b3log.solo.repository.impl.ArticleRepositoryImpl;
import org.b3log.solo.repository.impl.TagRepositoryImpl; import org.b3log.solo.repository.impl.PageRepositoryImpl;
import org.b3log.solo.service.PreferenceQueryService; import org.b3log.solo.repository.impl.TagRepositoryImpl;
import org.json.JSONArray; import org.b3log.solo.service.PreferenceQueryService;
import org.json.JSONObject; import org.json.JSONArray;
import org.json.JSONObject;
/**
* Site map (sitemap) processor. /**
* * Site map (sitemap) processor.
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> *
* @version 1.0.0.4, Jun 11, 2012 * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @since 0.3.1 * @version 1.0.0.4, Jun 11, 2012
*/ * @since 0.3.1
@RequestProcessor */
public final class SitemapProcessor { @RequestProcessor
public final class SitemapProcessor {
/**
* Logger. /**
*/ * Logger.
private static final Logger LOGGER = Logger.getLogger(SitemapProcessor.class.getName()); */
/** private static final Logger LOGGER = Logger.getLogger(SitemapProcessor.class.getName());
* Preference query service. /**
*/ * Preference query service.
private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance(); */
/** private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance();
* Article repository. /**
*/ * Article repository.
private ArticleRepositoryImpl articleRepository = ArticleRepositoryImpl.getInstance(); */
/** private ArticleRepositoryImpl articleRepository = ArticleRepositoryImpl.getInstance();
* Page repository. /**
*/ * Page repository.
private PageRepository pageRepository = PageRepositoryImpl.getInstance(); */
/** private PageRepository pageRepository = PageRepositoryImpl.getInstance();
* Tag repository. /**
*/ * Tag repository.
private TagRepository tagRepository = TagRepositoryImpl.getInstance(); */
/** private TagRepository tagRepository = TagRepositoryImpl.getInstance();
* Archive date repository. /**
*/ * Archive date repository.
private ArchiveDateRepository archiveDateRepository = ArchiveDateRepositoryImpl.getInstance(); */
private ArchiveDateRepository archiveDateRepository = ArchiveDateRepositoryImpl.getInstance();
/**
* Returns the sitemap. /**
* * Returns the sitemap.
* @param context the specified context *
*/ * @param context the specified context
@RequestProcessing(value = {"/sitemap.xml"}, method = HTTPRequestMethod.GET) */
public void sitemap(final HTTPRequestContext context) { @RequestProcessing(value = {"/sitemap.xml"}, method = HTTPRequestMethod.GET)
final TextXMLRenderer renderer = new TextXMLRenderer(); public void sitemap(final HTTPRequestContext context) {
context.setRenderer(renderer); final TextXMLRenderer renderer = new TextXMLRenderer();
context.setRenderer(renderer);
final Sitemap sitemap = new Sitemap();
final Sitemap sitemap = new Sitemap();
try {
final JSONObject preference = preferenceQueryService.getPreference(); try {
final JSONObject preference = preferenceQueryService.getPreference();
addArticles(sitemap, preference);
addNavigations(sitemap, preference); addArticles(sitemap, preference);
addTags(sitemap, preference); addNavigations(sitemap, preference);
addArchives(sitemap, preference); addTags(sitemap, preference);
addArchives(sitemap, preference);
LOGGER.log(Level.INFO, "Generating sitemap....");
final String content = sitemap.toString(); LOGGER.log(Level.INFO, "Generating sitemap....");
LOGGER.log(Level.INFO, "Generated sitemap"); final String content = sitemap.toString();
renderer.setContent(content); LOGGER.log(Level.INFO, "Generated sitemap");
} catch (final Exception e) { renderer.setContent(content);
LOGGER.log(Level.SEVERE, "Get blog article feed error", e); } catch (final Exception e) {
LOGGER.log(Level.SEVERE, "Get blog article feed error", e);
try {
context.getResponse().sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); try {
} catch (final IOException ex) { context.getResponse().sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
throw new RuntimeException(ex); } catch (final IOException ex) {
} throw new RuntimeException(ex);
} }
} }
}
/**
* Adds articles into the specified sitemap. /**
* * Adds articles into the specified sitemap.
* @param sitemap the specified sitemap *
* @param preference the specified preference * @param sitemap the specified sitemap
* @throws Exception exception * @param preference the specified preference
*/ * @throws Exception exception
private void addArticles(final Sitemap sitemap, final JSONObject preference) throws Exception { */
final String host = preference.getString(Preference.BLOG_HOST); private void addArticles(final Sitemap sitemap, final JSONObject preference) throws Exception {
final String host = preference.getString(Preference.BLOG_HOST);
// XXX: query all articles?
final Query query = new Query().setCurrentPageNum(1). // XXX: query all articles?
addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true). final Query query = new Query().setCurrentPageNum(1).
addSort(Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING); setFilter(new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true)).
addSort(Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING);
// Closes cache avoid Java heap space out of memory while caching
// query results // Closes cache avoid Java heap space out of memory while caching
articleRepository.setCacheEnabled(false); // query results
articleRepository.setCacheEnabled(false);
final JSONObject articleResult = articleRepository.get(query);
final JSONObject articleResult = articleRepository.get(query);
articleRepository.setCacheEnabled(true); // Restores cache
articleRepository.setCacheEnabled(true); // Restores cache
final JSONArray articles = articleResult.getJSONArray(Keys.RESULTS);
for (int i = 0; i < articles.length(); i++) { final JSONArray articles = articleResult.getJSONArray(Keys.RESULTS);
final JSONObject article = articles.getJSONObject(i); for (int i = 0; i < articles.length(); i++) {
final String permalink = article.getString(Article.ARTICLE_PERMALINK); final JSONObject article = articles.getJSONObject(i);
final String permalink = article.getString(Article.ARTICLE_PERMALINK);
final URL url = new URL();
url.setLoc("http://" + host + permalink); final URL url = new URL();
url.setLoc("http://" + host + permalink);
final Date updateDate = (Date) article.get(Article.ARTICLE_UPDATE_DATE);
final String lastMod = DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(updateDate); final Date updateDate = (Date) article.get(Article.ARTICLE_UPDATE_DATE);
url.setLastMod(lastMod); final String lastMod = DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(updateDate);
url.setLastMod(lastMod);
sitemap.addURL(url);
} sitemap.addURL(url);
} }
}
/**
* Adds navigations into the specified sitemap. /**
* * Adds navigations into the specified sitemap.
* @param sitemap the specified sitemap *
* @param preference the specified preference * @param sitemap the specified sitemap
* @throws Exception exception * @param preference the specified preference
*/ * @throws Exception exception
private void addNavigations(final Sitemap sitemap, final JSONObject preference) throws Exception { */
final String host = preference.getString(Preference.BLOG_HOST); private void addNavigations(final Sitemap sitemap, final JSONObject preference) throws Exception {
final String host = preference.getString(Preference.BLOG_HOST);
final JSONObject result = pageRepository.get(new Query());
final JSONArray pages = result.getJSONArray(Keys.RESULTS); final JSONObject result = pageRepository.get(new Query());
for (int i = 0; i < pages.length(); i++) { final JSONArray pages = result.getJSONArray(Keys.RESULTS);
final JSONObject page = pages.getJSONObject(i); for (int i = 0; i < pages.length(); i++) {
final String permalink = page.getString(Page.PAGE_PERMALINK); final JSONObject page = pages.getJSONObject(i);
final String permalink = page.getString(Page.PAGE_PERMALINK);
final URL url = new URL();
// The navigation maybe a page or a link final URL url = new URL();
// Just filters for user mistakes tolerance // The navigation maybe a page or a link
if (!permalink.contains("://")) { // Just filters for user mistakes tolerance
url.setLoc("http://" + host + permalink); if (!permalink.contains("://")) {
} else { url.setLoc("http://" + host + permalink);
url.setLoc(permalink); } else {
} url.setLoc(permalink);
}
sitemap.addURL(url);
} sitemap.addURL(url);
} }
}
/**
* Adds tags (tag-articles) and tags wall (/tags.html) into the specified /**
* sitemap. * Adds tags (tag-articles) and tags wall (/tags.html) into the specified
* * sitemap.
* @param sitemap the specified sitemap *
* @param preference the specified preference * @param sitemap the specified sitemap
* @throws Exception exception * @param preference the specified preference
*/ * @throws Exception exception
private void addTags(final Sitemap sitemap, final JSONObject preference) throws Exception { */
final String host = preference.getString(Preference.BLOG_HOST); private void addTags(final Sitemap sitemap, final JSONObject preference) throws Exception {
final String host = preference.getString(Preference.BLOG_HOST);
final JSONObject result = tagRepository.get(new Query());
final JSONArray tags = result.getJSONArray(Keys.RESULTS); final JSONObject result = tagRepository.get(new Query());
for (int i = 0; i < tags.length(); i++) { final JSONArray tags = result.getJSONArray(Keys.RESULTS);
final JSONObject tag = tags.getJSONObject(i); for (int i = 0; i < tags.length(); i++) {
final String link = URLEncoder.encode(tag.getString(Tag.TAG_TITLE), "UTF-8"); final JSONObject tag = tags.getJSONObject(i);
final String link = URLEncoder.encode(tag.getString(Tag.TAG_TITLE), "UTF-8");
final URL url = new URL();
url.setLoc("http://" + host + "/tags/" + link); final URL url = new URL();
url.setLoc("http://" + host + "/tags/" + link);
sitemap.addURL(url);
} sitemap.addURL(url);
}
// Tags wall
final URL url = new URL(); // Tags wall
url.setLoc("http://" + host + "/tags.html"); final URL url = new URL();
sitemap.addURL(url); url.setLoc("http://" + host + "/tags.html");
} sitemap.addURL(url);
}
/**
* Adds archives (archive-articles) into the specified sitemap. /**
* * Adds archives (archive-articles) into the specified sitemap.
* @param sitemap the specified sitemap *
* @param preference the specified preference * @param sitemap the specified sitemap
* @throws Exception exception * @param preference the specified preference
*/ * @throws Exception exception
private void addArchives(final Sitemap sitemap, final JSONObject preference) throws Exception { */
final String host = preference.getString(Preference.BLOG_HOST); private void addArchives(final Sitemap sitemap, final JSONObject preference) throws Exception {
final String host = preference.getString(Preference.BLOG_HOST);
final JSONObject result = archiveDateRepository.get(new Query());
final JSONArray archiveDates = result.getJSONArray(Keys.RESULTS); final JSONObject result = archiveDateRepository.get(new Query());
for (int i = 0; i < archiveDates.length(); i++) { final JSONArray archiveDates = result.getJSONArray(Keys.RESULTS);
final JSONObject archiveDate = archiveDates.getJSONObject(i); for (int i = 0; i < archiveDates.length(); i++) {
final long time = archiveDate.getLong(ArchiveDate.ARCHIVE_TIME); final JSONObject archiveDate = archiveDates.getJSONObject(i);
final String dateString = ArchiveDate.DATE_FORMAT.format(time); final long time = archiveDate.getLong(ArchiveDate.ARCHIVE_TIME);
final String dateString = ArchiveDate.DATE_FORMAT.format(time);
final URL url = new URL();
url.setLoc("http://" + host + "/archives/" + dateString); final URL url = new URL();
url.setLoc("http://" + host + "/archives/" + dateString);
sitemap.addURL(url);
} sitemap.addURL(url);
} }
} }
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.processor.util; package org.b3log.solo.processor.util;
import freemarker.template.Template; import freemarker.template.Template;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringEscapeUtils;
import org.b3log.latke.repository.RepositoryException; import org.b3log.latke.repository.RepositoryException;
import org.b3log.solo.util.Articles; import org.b3log.solo.util.Articles;
import org.b3log.solo.model.Article; import org.b3log.solo.model.Article;
import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.TagRepository; import org.b3log.solo.repository.TagRepository;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.Latkes; import org.b3log.latke.Latkes;
import org.b3log.latke.action.AbstractAction; import org.b3log.latke.action.AbstractAction;
import org.b3log.latke.event.Event; import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException; import org.b3log.latke.event.EventException;
import org.b3log.latke.event.EventManager; import org.b3log.latke.event.EventManager;
import org.b3log.latke.model.Pagination; import org.b3log.latke.model.Pagination;
import org.b3log.latke.model.Plugin; import org.b3log.latke.model.Plugin;
import org.b3log.latke.model.User; import org.b3log.latke.model.User;
import org.b3log.latke.plugin.ViewLoadEventData; import org.b3log.latke.plugin.ViewLoadEventData;
import org.b3log.latke.repository.FilterOperator; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.Query; import org.b3log.latke.service.ServiceException;
import org.b3log.latke.repository.SortDirection; import org.b3log.latke.util.*;
import org.b3log.latke.service.ServiceException; import org.b3log.latke.util.freemarker.Templates;
import org.b3log.latke.util.*; import org.b3log.solo.model.ArchiveDate;
import org.b3log.latke.util.freemarker.Templates; import org.b3log.solo.model.Link;
import org.b3log.solo.model.ArchiveDate; import org.b3log.solo.model.Preference;
import org.b3log.solo.model.Link; import org.b3log.solo.repository.CommentRepository;
import org.b3log.solo.model.Preference; import org.b3log.solo.repository.LinkRepository;
import org.b3log.solo.repository.CommentRepository; import org.b3log.solo.SoloServletListener;
import org.b3log.solo.repository.LinkRepository; import org.b3log.solo.model.*;
import org.b3log.solo.SoloServletListener; import org.b3log.solo.repository.ArchiveDateRepository;
import org.b3log.solo.model.*; import org.b3log.solo.repository.PageRepository;
import org.b3log.solo.repository.ArchiveDateRepository; import org.b3log.solo.repository.StatisticRepository;
import org.b3log.solo.repository.PageRepository; import org.b3log.solo.repository.UserRepository;
import org.b3log.solo.repository.StatisticRepository; import org.b3log.solo.repository.impl.ArchiveDateRepositoryImpl;
import org.b3log.solo.repository.UserRepository; import org.b3log.solo.repository.impl.ArticleRepositoryImpl;
import org.b3log.solo.repository.impl.ArchiveDateRepositoryImpl; import org.b3log.solo.repository.impl.CommentRepositoryImpl;
import org.b3log.solo.repository.impl.ArticleRepositoryImpl; import org.b3log.solo.repository.impl.LinkRepositoryImpl;
import org.b3log.solo.repository.impl.CommentRepositoryImpl; import org.b3log.solo.repository.impl.PageRepositoryImpl;
import org.b3log.solo.repository.impl.LinkRepositoryImpl; import org.b3log.solo.repository.impl.StatisticRepositoryImpl;
import org.b3log.solo.repository.impl.PageRepositoryImpl; import org.b3log.solo.repository.impl.TagRepositoryImpl;
import org.b3log.solo.repository.impl.StatisticRepositoryImpl; import org.b3log.solo.repository.impl.UserRepositoryImpl;
import org.b3log.solo.repository.impl.TagRepositoryImpl; import org.b3log.solo.service.ArticleQueryService;
import org.b3log.solo.repository.impl.UserRepositoryImpl; import org.b3log.solo.util.Tags;
import org.b3log.solo.service.ArticleQueryService; import org.b3log.solo.util.Users;
import org.b3log.solo.util.Tags; import org.json.JSONArray;
import org.b3log.solo.util.Users; import org.json.JSONException;
import org.json.JSONArray; import org.json.JSONObject;
import org.json.JSONException;
import org.json.JSONObject; /**
* Filler utilities.
/** *
* Filler utilities. * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* * @version 1.0.5.9, May 22, 2012
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> * @since 0.3.1
* @version 1.0.5.9, May 22, 2012 */
* @since 0.3.1 public final class Filler {
*/
public final class Filler { /**
* Logger.
/** */
* Logger. private static final Logger LOGGER = Logger.getLogger(Filler.class.getName());
*/ /**
private static final Logger LOGGER = Logger.getLogger(Filler.class.getName()); * Article repository.
/** */
* Article repository. private ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance();
*/ /**
private ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance(); * Comment repository.
/** */
* Comment repository. private CommentRepository commentRepository = CommentRepositoryImpl.getInstance();
*/ /**
private CommentRepository commentRepository = CommentRepositoryImpl.getInstance(); * Archive date repository.
/** */
* Archive date repository. private ArchiveDateRepository archiveDateRepository = ArchiveDateRepositoryImpl.getInstance();
*/ /**
private ArchiveDateRepository archiveDateRepository = ArchiveDateRepositoryImpl.getInstance(); * Tag repository.
/** */
* Tag repository. private TagRepository tagRepository = TagRepositoryImpl.getInstance();
*/ /**
private TagRepository tagRepository = TagRepositoryImpl.getInstance(); * Article utilities.
/** */
* Article utilities. private Articles articleUtils = Articles.getInstance();
*/ /**
private Articles articleUtils = Articles.getInstance(); * Tag utilities.
/** */
* Tag utilities. private Tags tagUtils = Tags.getInstance();
*/ /**
private Tags tagUtils = Tags.getInstance(); * Link repository.
/** */
* Link repository. private LinkRepository linkRepository = LinkRepositoryImpl.getInstance();
*/ /**
private LinkRepository linkRepository = LinkRepositoryImpl.getInstance(); * Page repository.
/** */
* Page repository. private PageRepository pageRepository = PageRepositoryImpl.getInstance();
*/ /**
private PageRepository pageRepository = PageRepositoryImpl.getInstance(); * Statistic repository.
/** */
* Statistic repository. private StatisticRepository statisticRepository = StatisticRepositoryImpl.getInstance();
*/ /**
private StatisticRepository statisticRepository = StatisticRepositoryImpl.getInstance(); * User repository.
/** */
* User repository. private UserRepository userRepository = UserRepositoryImpl.getInstance();
*/ /**
private UserRepository userRepository = UserRepositoryImpl.getInstance(); * Article query service.
/** */
* Article query service. private ArticleQueryService articleQueryService = ArticleQueryService.getInstance();
*/ /**
private ArticleQueryService articleQueryService = ArticleQueryService.getInstance(); * {@code true} for published.
/** */
* {@code true} for published. private static final boolean PUBLISHED = true;
*/
private static final boolean PUBLISHED = true; /**
* Fills articles in index.ftl.
/** *
* Fills articles in index.ftl. * @param dataModel data model
* * @param currentPageNum current page number
* @param dataModel data model * @param preference the specified preference
* @param currentPageNum current page number * @throws ServiceException service exception
* @param preference the specified preference */
* @throws ServiceException service exception public void fillIndexArticles(final Map<String, Object> dataModel, final int currentPageNum, final JSONObject preference)
*/ throws ServiceException {
public void fillIndexArticles(final Map<String, Object> dataModel, final int currentPageNum, final JSONObject preference) Stopwatchs.start("Fill Index Articles");
throws ServiceException {
Stopwatchs.start("Fill Index Articles"); try {
final int pageSize = preference.getInt(Preference.ARTICLE_LIST_DISPLAY_COUNT);
try { final int windowSize = preference.getInt(Preference.ARTICLE_LIST_PAGINATION_WINDOW_SIZE);
final int pageSize = preference.getInt(Preference.ARTICLE_LIST_DISPLAY_COUNT);
final int windowSize = preference.getInt(Preference.ARTICLE_LIST_PAGINATION_WINDOW_SIZE); final JSONObject statistic = statisticRepository.get(Statistic.STATISTIC);
final int publishedArticleCnt = statistic.getInt(Statistic.STATISTIC_PUBLISHED_ARTICLE_COUNT);
final JSONObject statistic = statisticRepository.get(Statistic.STATISTIC); final int pageCount = (int) Math.ceil((double) publishedArticleCnt / (double) pageSize);
final int publishedArticleCnt = statistic.getInt(Statistic.STATISTIC_PUBLISHED_ARTICLE_COUNT);
final int pageCount = (int) Math.ceil((double) publishedArticleCnt / (double) pageSize); final Query query = new Query().setCurrentPageNum(currentPageNum).setPageSize(pageSize).setPageCount(pageCount).
setFilter(new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, PUBLISHED)).
final Query query = new Query().setCurrentPageNum(currentPageNum).setPageSize(pageSize).setPageCount(pageCount). addSort(Article.ARTICLE_PUT_TOP, SortDirection.DESCENDING).
addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, PUBLISHED). index(Article.ARTICLE_PERMALINK);
addSort(Article.ARTICLE_PUT_TOP, SortDirection.DESCENDING).
index(Article.ARTICLE_PERMALINK); if (preference.getBoolean(Preference.ENABLE_ARTICLE_UPDATE_HINT)) {
query.addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING);
if (preference.getBoolean(Preference.ENABLE_ARTICLE_UPDATE_HINT)) { } else {
query.addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING); query.addSort(Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING);
} else { }
query.addSort(Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING);
} final JSONObject result = articleRepository.get(query);
final List<Integer> pageNums = Paginator.paginate(currentPageNum, pageSize, pageCount, windowSize);
final JSONObject result = articleRepository.get(query); if (0 != pageNums.size()) {
final List<Integer> pageNums = Paginator.paginate(currentPageNum, pageSize, pageCount, windowSize); dataModel.put(Pagination.PAGINATION_FIRST_PAGE_NUM, pageNums.get(0));
if (0 != pageNums.size()) { dataModel.put(Pagination.PAGINATION_LAST_PAGE_NUM, pageNums.get(pageNums.size() - 1));
dataModel.put(Pagination.PAGINATION_FIRST_PAGE_NUM, pageNums.get(0)); }
dataModel.put(Pagination.PAGINATION_LAST_PAGE_NUM, pageNums.get(pageNums.size() - 1));
} dataModel.put(Pagination.PAGINATION_PAGE_COUNT, pageCount);
dataModel.put(Pagination.PAGINATION_PAGE_NUMS, pageNums);
dataModel.put(Pagination.PAGINATION_PAGE_COUNT, pageCount);
dataModel.put(Pagination.PAGINATION_PAGE_NUMS, pageNums); final List<JSONObject> articles = org.b3log.latke.util.CollectionUtils.jsonArrayToList(result.getJSONArray(Keys.RESULTS));
final List<JSONObject> articles = org.b3log.latke.util.CollectionUtils.jsonArrayToList(result.getJSONArray(Keys.RESULTS)); final boolean hasMultipleUsers = Users.getInstance().hasMultipleUsers();
if (hasMultipleUsers) {
final boolean hasMultipleUsers = Users.getInstance().hasMultipleUsers(); setArticlesExProperties(articles, preference);
if (hasMultipleUsers) { } else {
setArticlesExProperties(articles, preference); if (!articles.isEmpty()) {
} else { final JSONObject author = articleUtils.getAuthor(articles.get(0));
if (!articles.isEmpty()) { setArticlesExProperties(articles, author, preference);
final JSONObject author = articleUtils.getAuthor(articles.get(0)); }
setArticlesExProperties(articles, author, preference); }
}
} dataModel.put(Article.ARTICLES, articles);
} catch (final JSONException e) {
dataModel.put(Article.ARTICLES, articles); LOGGER.log(Level.SEVERE, "Fills index articles failed", e);
} catch (final JSONException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills index articles failed", e); } catch (final RepositoryException e) {
throw new ServiceException(e); LOGGER.log(Level.SEVERE, "Fills index articles failed", e);
} catch (final RepositoryException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills index articles failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Fills links.
/** *
* Fills links. * @param dataModel data model
* * @throws ServiceException service exception
* @param dataModel data model */
* @throws ServiceException service exception public void fillLinks(final Map<String, Object> dataModel) throws ServiceException {
*/ Stopwatchs.start("Fill Links");
public void fillLinks(final Map<String, Object> dataModel) throws ServiceException { try {
Stopwatchs.start("Fill Links"); final Map<String, SortDirection> sorts = new HashMap<String, SortDirection>();
try { sorts.put(Link.LINK_ORDER, SortDirection.ASCENDING);
final Map<String, SortDirection> sorts = new HashMap<String, SortDirection>(); final Query query = new Query().addSort(Link.LINK_ORDER, SortDirection.ASCENDING).setPageCount(1);
sorts.put(Link.LINK_ORDER, SortDirection.ASCENDING); final JSONObject linkResult = linkRepository.get(query);
final Query query = new Query().addSort(Link.LINK_ORDER, SortDirection.ASCENDING).setPageCount(1); final List<JSONObject> links = org.b3log.latke.util.CollectionUtils.jsonArrayToList(linkResult.getJSONArray(Keys.RESULTS));
final JSONObject linkResult = linkRepository.get(query);
final List<JSONObject> links = org.b3log.latke.util.CollectionUtils.jsonArrayToList(linkResult.getJSONArray(Keys.RESULTS)); dataModel.put(Link.LINKS, links);
} catch (final JSONException e) {
dataModel.put(Link.LINKS, links); LOGGER.log(Level.SEVERE, "Fills links failed", e);
} catch (final JSONException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills links failed", e); } catch (final RepositoryException e) {
throw new ServiceException(e); LOGGER.log(Level.SEVERE, "Fills links failed", e);
} catch (final RepositoryException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills links failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); Stopwatchs.end();
} }
Stopwatchs.end();
} /**
* Fills most used tags.
/** *
* Fills most used tags. * @param dataModel data model
* * @param preference the specified preference
* @param dataModel data model * @throws ServiceException service exception
* @param preference the specified preference */
* @throws ServiceException service exception public void fillMostUsedTags(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
*/ Stopwatchs.start("Fill Most Used Tags");
public void fillMostUsedTags(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
Stopwatchs.start("Fill Most Used Tags"); try {
LOGGER.finer("Filling most used tags....");
try { final int mostUsedTagDisplayCnt = preference.getInt(Preference.MOST_USED_TAG_DISPLAY_CNT);
LOGGER.finer("Filling most used tags....");
final int mostUsedTagDisplayCnt = preference.getInt(Preference.MOST_USED_TAG_DISPLAY_CNT); final List<JSONObject> tags = tagRepository.getMostUsedTags(mostUsedTagDisplayCnt);
tagUtils.removeForUnpublishedArticles(tags);
final List<JSONObject> tags = tagRepository.getMostUsedTags(mostUsedTagDisplayCnt);
tagUtils.removeForUnpublishedArticles(tags); dataModel.put(Common.MOST_USED_TAGS, tags);
} catch (final JSONException e) {
dataModel.put(Common.MOST_USED_TAGS, tags); LOGGER.log(Level.SEVERE, "Fills most used tags failed", e);
} catch (final JSONException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills most used tags failed", e); } catch (final RepositoryException e) {
throw new ServiceException(e); LOGGER.log(Level.SEVERE, "Fills most used tags failed", e);
} catch (final RepositoryException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills most used tags failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Fills archive dates.
/** *
* Fills archive dates. * @param dataModel data model
* * @param preference the specified preference
* @param dataModel data model * @throws ServiceException service exception
* @param preference the specified preference */
* @throws ServiceException service exception public void fillArchiveDates(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
*/ Stopwatchs.start("Fill Archive Dates");
public void fillArchiveDates(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
Stopwatchs.start("Fill Archive Dates"); try {
LOGGER.finer("Filling archive dates....");
try { final List<JSONObject> archiveDates = archiveDateRepository.getArchiveDates();
LOGGER.finer("Filling archive dates....");
final List<JSONObject> archiveDates = archiveDateRepository.getArchiveDates(); final String localeString = preference.getString(Preference.LOCALE_STRING);
final String language = Locales.getLanguage(localeString);
final String localeString = preference.getString(Preference.LOCALE_STRING);
final String language = Locales.getLanguage(localeString); for (final JSONObject archiveDate : archiveDates) {
final long time = archiveDate.getLong(ArchiveDate.ARCHIVE_TIME);
for (final JSONObject archiveDate : archiveDates) { final String dateString = ArchiveDate.DATE_FORMAT.format(time);
final long time = archiveDate.getLong(ArchiveDate.ARCHIVE_TIME); final String[] dateStrings = dateString.split("/");
final String dateString = ArchiveDate.DATE_FORMAT.format(time); final String year = dateStrings[0];
final String[] dateStrings = dateString.split("/"); final String month = dateStrings[1];
final String year = dateStrings[0]; archiveDate.put(ArchiveDate.ARCHIVE_DATE_YEAR, year);
final String month = dateStrings[1];
archiveDate.put(ArchiveDate.ARCHIVE_DATE_YEAR, year); archiveDate.put(ArchiveDate.ARCHIVE_DATE_MONTH, month);
if ("en".equals(language)) {
archiveDate.put(ArchiveDate.ARCHIVE_DATE_MONTH, month); final String monthName = Dates.EN_MONTHS.get(month);
if ("en".equals(language)) { archiveDate.put(Common.MONTH_NAME, monthName);
final String monthName = Dates.EN_MONTHS.get(month); }
archiveDate.put(Common.MONTH_NAME, monthName); }
}
} dataModel.put(ArchiveDate.ARCHIVE_DATES, archiveDates);
} catch (final JSONException e) {
dataModel.put(ArchiveDate.ARCHIVE_DATES, archiveDates); LOGGER.log(Level.SEVERE, "Fills archive dates failed", e);
} catch (final JSONException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills archive dates failed", e); } catch (final RepositoryException e) {
throw new ServiceException(e); LOGGER.log(Level.SEVERE, "Fills archive dates failed", e);
} catch (final RepositoryException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills archive dates failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Fills most view count articles.
/** *
* Fills most view count articles. * @param dataModel data model
* * @param preference the specified preference
* @param dataModel data model * @throws ServiceException service exception
* @param preference the specified preference */
* @throws ServiceException service exception public void fillMostViewCountArticles(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
*/ Stopwatchs.start("Fill Most View Articles");
public void fillMostViewCountArticles(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException { try {
Stopwatchs.start("Fill Most View Articles"); LOGGER.finer("Filling the most view count articles....");
try { final int mostCommentArticleDisplayCnt = preference.getInt(Preference.MOST_VIEW_ARTICLE_DISPLAY_CNT);
LOGGER.finer("Filling the most view count articles...."); final List<JSONObject> mostViewCountArticles = articleRepository.getMostViewCountArticles(mostCommentArticleDisplayCnt);
final int mostCommentArticleDisplayCnt = preference.getInt(Preference.MOST_VIEW_ARTICLE_DISPLAY_CNT);
final List<JSONObject> mostViewCountArticles = articleRepository.getMostViewCountArticles(mostCommentArticleDisplayCnt); dataModel.put(Common.MOST_VIEW_COUNT_ARTICLES, mostViewCountArticles);
dataModel.put(Common.MOST_VIEW_COUNT_ARTICLES, mostViewCountArticles); } catch (final Exception e) {
LOGGER.log(Level.SEVERE, "Fills most view count articles failed", e);
} catch (final Exception e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills most view count articles failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Fills most comments articles.
/** *
* Fills most comments articles. * @param dataModel data model
* * @param preference the specified preference
* @param dataModel data model * @throws ServiceException service exception
* @param preference the specified preference */
* @throws ServiceException service exception public void fillMostCommentArticles(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
*/ Stopwatchs.start("Fill Most CMMTs Articles");
public void fillMostCommentArticles(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
Stopwatchs.start("Fill Most CMMTs Articles"); try {
LOGGER.finer("Filling most comment articles....");
try { final int mostCommentArticleDisplayCnt = preference.getInt(Preference.MOST_COMMENT_ARTICLE_DISPLAY_CNT);
LOGGER.finer("Filling most comment articles...."); final List<JSONObject> mostCommentArticles = articleRepository.getMostCommentArticles(mostCommentArticleDisplayCnt);
final int mostCommentArticleDisplayCnt = preference.getInt(Preference.MOST_COMMENT_ARTICLE_DISPLAY_CNT);
final List<JSONObject> mostCommentArticles = articleRepository.getMostCommentArticles(mostCommentArticleDisplayCnt); dataModel.put(Common.MOST_COMMENT_ARTICLES, mostCommentArticles);
} catch (final Exception e) {
dataModel.put(Common.MOST_COMMENT_ARTICLES, mostCommentArticles); LOGGER.log(Level.SEVERE, "Fills most comment articles failed", e);
} catch (final Exception e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills most comment articles failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Fills post articles recently.
/** *
* Fills post articles recently. * @param dataModel data model
* * @param preference the specified preference
* @param dataModel data model * @throws ServiceException service exception
* @param preference the specified preference */
* @throws ServiceException service exception public void fillRecentArticles(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
*/ Stopwatchs.start("Fill Recent Articles");
public void fillRecentArticles(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
Stopwatchs.start("Fill Recent Articles"); try {
final int recentArticleDisplayCnt = preference.getInt(Preference.RECENT_ARTICLE_DISPLAY_CNT);
try {
final int recentArticleDisplayCnt = preference.getInt(Preference.RECENT_ARTICLE_DISPLAY_CNT); final List<JSONObject> recentArticles = articleRepository.getRecentArticles(recentArticleDisplayCnt);
final List<JSONObject> recentArticles = articleRepository.getRecentArticles(recentArticleDisplayCnt); dataModel.put(Common.RECENT_ARTICLES, recentArticles);
dataModel.put(Common.RECENT_ARTICLES, recentArticles); } catch (final JSONException e) {
LOGGER.log(Level.SEVERE, "Fills recent articles failed", e);
} catch (final JSONException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills recent articles failed", e); } catch (final RepositoryException e) {
throw new ServiceException(e); LOGGER.log(Level.SEVERE, "Fills recent articles failed", e);
} catch (final RepositoryException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills recent articles failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Fills post comments recently.
/** *
* Fills post comments recently. * @param dataModel data model
* * @param preference the specified preference
* @param dataModel data model * @throws ServiceException service exception
* @param preference the specified preference */
* @throws ServiceException service exception public void fillRecentComments(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
*/ Stopwatchs.start("Fill Recent Comments");
public void fillRecentComments(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException { try {
Stopwatchs.start("Fill Recent Comments"); LOGGER.finer("Filling recent comments....");
try { final int recentCommentDisplayCnt = preference.getInt(Preference.RECENT_COMMENT_DISPLAY_CNT);
LOGGER.finer("Filling recent comments....");
final int recentCommentDisplayCnt = preference.getInt(Preference.RECENT_COMMENT_DISPLAY_CNT); final List<JSONObject> recentComments = commentRepository.getRecentComments(recentCommentDisplayCnt);
final List<JSONObject> recentComments = commentRepository.getRecentComments(recentCommentDisplayCnt); for (final JSONObject comment : recentComments) {
final String content = comment.getString(Comment.COMMENT_CONTENT).replaceAll(SoloServletListener.ENTER_ESC, "&nbsp;");
for (final JSONObject comment : recentComments) { comment.put(Comment.COMMENT_CONTENT, content);
final String content = comment.getString(Comment.COMMENT_CONTENT).replaceAll(SoloServletListener.ENTER_ESC, "&nbsp;"); comment.put(Comment.COMMENT_NAME, StringEscapeUtils.escapeHtml(comment.getString(Comment.COMMENT_NAME)));
comment.put(Comment.COMMENT_CONTENT, content); comment.put(Comment.COMMENT_URL, StringEscapeUtils.escapeHtml(comment.getString(Comment.COMMENT_URL)));
comment.put(Comment.COMMENT_NAME, StringEscapeUtils.escapeHtml(comment.getString(Comment.COMMENT_NAME)));
comment.put(Comment.COMMENT_URL, StringEscapeUtils.escapeHtml(comment.getString(Comment.COMMENT_URL))); comment.remove(Comment.COMMENT_EMAIL); // Erases email for security reason
}
comment.remove(Comment.COMMENT_EMAIL); // Erases email for security reason
} dataModel.put(Common.RECENT_COMMENTS, recentComments);
dataModel.put(Common.RECENT_COMMENTS, recentComments); } catch (final JSONException e) {
LOGGER.log(Level.SEVERE, "Fills recent comments failed", e);
} catch (final JSONException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills recent comments failed", e); } catch (final RepositoryException e) {
throw new ServiceException(e); LOGGER.log(Level.SEVERE, "Fills recent comments failed", e);
} catch (final RepositoryException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills recent comments failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Fills footer.ftl.
/** *
* Fills footer.ftl. * @param dataModel data model
* * @param preference the specified preference
* @param dataModel data model * @throws ServiceException service exception
* @param preference the specified preference */
* @throws ServiceException service exception public void fillBlogFooter(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
*/ Stopwatchs.start("Fill Footer");
public void fillBlogFooter(final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException { try {
Stopwatchs.start("Fill Footer"); LOGGER.finer("Filling footer....");
try { final String blogTitle = preference.getString(Preference.BLOG_TITLE);
LOGGER.finer("Filling footer...."); dataModel.put(Preference.BLOG_TITLE, blogTitle);
final String blogTitle = preference.getString(Preference.BLOG_TITLE); final String blogHost = preference.getString(Preference.BLOG_HOST);
dataModel.put(Preference.BLOG_TITLE, blogTitle); dataModel.put(Preference.BLOG_HOST, blogHost);
final String blogHost = preference.getString(Preference.BLOG_HOST);
dataModel.put(Preference.BLOG_HOST, blogHost); dataModel.put(Common.VERSION, SoloServletListener.VERSION);
dataModel.put(Common.STATIC_RESOURCE_VERSION, Latkes.getStaticResourceVersion());
dataModel.put(Common.VERSION, SoloServletListener.VERSION); dataModel.put(Common.YEAR, String.valueOf(Calendar.getInstance().get(Calendar.YEAR)));
dataModel.put(Common.STATIC_RESOURCE_VERSION, Latkes.getStaticResourceVersion());
dataModel.put(Common.YEAR, String.valueOf(Calendar.getInstance().get(Calendar.YEAR))); dataModel.put(Keys.Server.STATIC_SERVER, Latkes.getStaticServer());
dataModel.put(Keys.Server.SERVER, Latkes.getServer());
dataModel.put(Keys.Server.STATIC_SERVER, Latkes.getStaticServer());
dataModel.put(Keys.Server.SERVER, Latkes.getServer());
// Activates plugins
try {
// Activates plugins final ViewLoadEventData data = new ViewLoadEventData();
try { data.setViewName("footer.ftl");
final ViewLoadEventData data = new ViewLoadEventData(); data.setDataModel(dataModel);
data.setViewName("footer.ftl"); EventManager.getInstance().fireEventSynchronously(new Event<ViewLoadEventData>(AbstractAction.FREEMARKER_ACTION, data));
data.setDataModel(dataModel); if (Strings.isEmptyOrNull((String) dataModel.get(Plugin.PLUGINS))) {
EventManager.getInstance().fireEventSynchronously(new Event<ViewLoadEventData>(AbstractAction.FREEMARKER_ACTION, data)); // There is no plugin for this template, fill ${plugins} with blank.
if (Strings.isEmptyOrNull((String) dataModel.get(Plugin.PLUGINS))) { dataModel.put(Plugin.PLUGINS, "");
// There is no plugin for this template, fill ${plugins} with blank. }
dataModel.put(Plugin.PLUGINS, ""); } catch (final EventException e) {
} LOGGER.log(Level.WARNING, "Event[FREEMARKER_ACTION] handle failed, ignores this exception for kernel health", e);
} catch (final EventException e) { }
LOGGER.log(Level.WARNING, "Event[FREEMARKER_ACTION] handle failed, ignores this exception for kernel health", e); } catch (final JSONException e) {
} LOGGER.log(Level.SEVERE, "Fills blog footer failed", e);
} catch (final JSONException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills blog footer failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Fills header.ftl.
/** *
* Fills header.ftl. * @param request the specified HTTP servlet request
* * @param dataModel data model
* @param request the specified HTTP servlet request * @param preference the specified preference
* @param dataModel data model * @throws ServiceException service exception
* @param preference the specified preference */
* @throws ServiceException service exception public void fillBlogHeader(final HttpServletRequest request, final Map<String, Object> dataModel, final JSONObject preference)
*/ throws ServiceException {
public void fillBlogHeader(final HttpServletRequest request, final Map<String, Object> dataModel, final JSONObject preference) Stopwatchs.start("Fill Header");
throws ServiceException { try {
Stopwatchs.start("Fill Header"); LOGGER.fine("Filling header....");
try { dataModel.put(Preference.ARTICLE_LIST_DISPLAY_COUNT, preference.getInt(Preference.ARTICLE_LIST_DISPLAY_COUNT));
LOGGER.fine("Filling header...."); dataModel.put(Preference.ARTICLE_LIST_PAGINATION_WINDOW_SIZE,
dataModel.put(Preference.ARTICLE_LIST_DISPLAY_COUNT, preference.getInt(Preference.ARTICLE_LIST_DISPLAY_COUNT)); preference.getInt(Preference.ARTICLE_LIST_PAGINATION_WINDOW_SIZE));
dataModel.put(Preference.ARTICLE_LIST_PAGINATION_WINDOW_SIZE, dataModel.put(Preference.LOCALE_STRING, preference.getString(Preference.LOCALE_STRING));
preference.getInt(Preference.ARTICLE_LIST_PAGINATION_WINDOW_SIZE)); dataModel.put(Preference.BLOG_TITLE, preference.getString(Preference.BLOG_TITLE));
dataModel.put(Preference.LOCALE_STRING, preference.getString(Preference.LOCALE_STRING)); dataModel.put(Preference.BLOG_SUBTITLE, preference.getString(Preference.BLOG_SUBTITLE));
dataModel.put(Preference.BLOG_TITLE, preference.getString(Preference.BLOG_TITLE)); dataModel.put(Preference.HTML_HEAD, preference.getString(Preference.HTML_HEAD));
dataModel.put(Preference.BLOG_SUBTITLE, preference.getString(Preference.BLOG_SUBTITLE)); dataModel.put(Preference.META_KEYWORDS, preference.getString(Preference.META_KEYWORDS));
dataModel.put(Preference.HTML_HEAD, preference.getString(Preference.HTML_HEAD)); dataModel.put(Preference.META_DESCRIPTION, preference.getString(Preference.META_DESCRIPTION));
dataModel.put(Preference.META_KEYWORDS, preference.getString(Preference.META_KEYWORDS)); dataModel.put(Common.YEAR, String.valueOf(Calendar.getInstance().get(Calendar.YEAR)));
dataModel.put(Preference.META_DESCRIPTION, preference.getString(Preference.META_DESCRIPTION));
dataModel.put(Common.YEAR, String.valueOf(Calendar.getInstance().get(Calendar.YEAR))); final String noticeBoard = preference.getString(Preference.NOTICE_BOARD);
dataModel.put(Preference.NOTICE_BOARD, noticeBoard);
final String noticeBoard = preference.getString(Preference.NOTICE_BOARD);
dataModel.put(Preference.NOTICE_BOARD, noticeBoard); final Query query = new Query().setPageCount(1);
final JSONObject result = userRepository.get(query);
final Query query = new Query().setPageCount(1); final JSONArray users = result.getJSONArray(Keys.RESULTS);
final JSONObject result = userRepository.get(query); final List<JSONObject> userList = CollectionUtils.jsonArrayToList(users);
final JSONArray users = result.getJSONArray(Keys.RESULTS); dataModel.put(User.USERS, userList);
final List<JSONObject> userList = CollectionUtils.jsonArrayToList(users); for (final JSONObject user : userList) {
dataModel.put(User.USERS, userList); user.remove(User.USER_EMAIL);
for (final JSONObject user : userList) { }
user.remove(User.USER_EMAIL);
} final String skinDirName = (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME);
dataModel.put(Skin.SKIN_DIR_NAME, skinDirName);
final String skinDirName = (String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME);
dataModel.put(Skin.SKIN_DIR_NAME, skinDirName); Keys.fillServer(dataModel);
fillMinified(dataModel);
Keys.fillServer(dataModel); fillPageNavigations(dataModel);
fillMinified(dataModel); fillStatistic(dataModel);
fillPageNavigations(dataModel); } catch (final JSONException e) {
fillStatistic(dataModel); LOGGER.log(Level.SEVERE, "Fills blog header failed", e);
} catch (final JSONException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills blog header failed", e); } catch (final RepositoryException e) {
throw new ServiceException(e); LOGGER.log(Level.SEVERE, "Fills blog header failed", e);
} catch (final RepositoryException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills blog header failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Fills minified directory and file postfix for static JavaScript, CSS.
/** *
* Fills minified directory and file postfix for static JavaScript, CSS. * @param dataModel the specified data model
* */
* @param dataModel the specified data model public void fillMinified(final Map<String, Object> dataModel) {
*/ switch (Latkes.getRuntimeMode()) {
public void fillMinified(final Map<String, Object> dataModel) { case DEVELOPMENT:
switch (Latkes.getRuntimeMode()) { dataModel.put(Common.MINI_POSTFIX, "");
case DEVELOPMENT: break;
dataModel.put(Common.MINI_POSTFIX, ""); case PRODUCTION:
break; dataModel.put(Common.MINI_POSTFIX, Common.MINI_POSTFIX_VALUE);
case PRODUCTION: break;
dataModel.put(Common.MINI_POSTFIX, Common.MINI_POSTFIX_VALUE); default:
break; throw new AssertionError();
default: }
throw new AssertionError(); }
}
} /**
* Fills side.ftl.
/** *
* Fills side.ftl. * @param request the specified HTTP servlet request
* * @param dataModel data model
* @param request the specified HTTP servlet request * @param preference the specified preference
* @param dataModel data model * @throws ServiceException service exception
* @param preference the specified preference */
* @throws ServiceException service exception public void fillSide(final HttpServletRequest request, final Map<String, Object> dataModel, final JSONObject preference)
*/ throws ServiceException {
public void fillSide(final HttpServletRequest request, final Map<String, Object> dataModel, final JSONObject preference) Stopwatchs.start("Fill Side");
throws ServiceException { try {
Stopwatchs.start("Fill Side"); LOGGER.fine("Filling side....");
try {
LOGGER.fine("Filling side...."); final Template template = Templates.getTemplate((String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), "side.ftl");
final Template template = Templates.getTemplate((String) request.getAttribute(Keys.TEMAPLTE_DIR_NAME), "side.ftl"); if (null == template) {
LOGGER.fine("The skin dose not contain [side.ftl] template");
if (null == template) {
LOGGER.fine("The skin dose not contain [side.ftl] template"); return;
}
return;
} // TODO: fillRecentArticles(dataModel, preference);
if (Templates.hasExpression(template, "<#list links as link>")) {
// TODO: fillRecentArticles(dataModel, preference); fillLinks(dataModel);
if (Templates.hasExpression(template, "<#list links as link>")) { }
fillLinks(dataModel);
} if (Templates.hasExpression(template, "<#list recentComments as comment>")) {
fillRecentComments(dataModel, preference);
if (Templates.hasExpression(template, "<#list recentComments as comment>")) { }
fillRecentComments(dataModel, preference);
} if (Templates.hasExpression(template, "<#list mostUsedTags as tag>")) {
fillMostUsedTags(dataModel, preference);
if (Templates.hasExpression(template, "<#list mostUsedTags as tag>")) { }
fillMostUsedTags(dataModel, preference);
} if (Templates.hasExpression(template, "<#list mostCommentArticles as article>")) {
fillMostCommentArticles(dataModel, preference);
if (Templates.hasExpression(template, "<#list mostCommentArticles as article>")) { }
fillMostCommentArticles(dataModel, preference);
} if (Templates.hasExpression(template, "<#list mostViewCountArticles as article>")) {
fillMostViewCountArticles(dataModel, preference);
if (Templates.hasExpression(template, "<#list mostViewCountArticles as article>")) { }
fillMostViewCountArticles(dataModel, preference);
} if (Templates.hasExpression(template, "<#list archiveDates as archiveDate>")) {
fillArchiveDates(dataModel, preference);
if (Templates.hasExpression(template, "<#list archiveDates as archiveDate>")) { }
fillArchiveDates(dataModel, preference); } catch (final ServiceException e) {
} LOGGER.log(Level.SEVERE, "Fills side failed", e);
} catch (final ServiceException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills side failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Fills the specified template.
/** *
* Fills the specified template. * @param template the specified template
* * @param dataModel data model
* @param template the specified template * @param preference the specified preference
* @param dataModel data model * @throws ServiceException service exception
* @param preference the specified preference */
* @throws ServiceException service exception public void fillUserTemplate(final Template template, final Map<String, Object> dataModel, final JSONObject preference)
*/ throws ServiceException {
public void fillUserTemplate(final Template template, final Map<String, Object> dataModel, final JSONObject preference) Stopwatchs.start("Fill User Template[name=" + template.getName() + "]");
throws ServiceException { try {
Stopwatchs.start("Fill User Template[name=" + template.getName() + "]"); LOGGER.log(Level.FINE, "Filling user template[name{0}]", template.getName());
try {
LOGGER.log(Level.FINE, "Filling user template[name{0}]", template.getName()); if (Templates.hasExpression(template, "<#list links as link>")) {
fillLinks(dataModel);
if (Templates.hasExpression(template, "<#list links as link>")) { }
fillLinks(dataModel);
} if (Templates.hasExpression(template, "<#list recentComments as comment>")) {
fillRecentComments(dataModel, preference);
if (Templates.hasExpression(template, "<#list recentComments as comment>")) { }
fillRecentComments(dataModel, preference);
} if (Templates.hasExpression(template, "<#list mostUsedTags as tag>")) {
fillMostUsedTags(dataModel, preference);
if (Templates.hasExpression(template, "<#list mostUsedTags as tag>")) { }
fillMostUsedTags(dataModel, preference);
} if (Templates.hasExpression(template, "<#list mostCommentArticles as article>")) {
fillMostCommentArticles(dataModel, preference);
if (Templates.hasExpression(template, "<#list mostCommentArticles as article>")) { }
fillMostCommentArticles(dataModel, preference);
} if (Templates.hasExpression(template, "<#list mostViewCountArticles as article>")) {
fillMostViewCountArticles(dataModel, preference);
if (Templates.hasExpression(template, "<#list mostViewCountArticles as article>")) { }
fillMostViewCountArticles(dataModel, preference);
} if (Templates.hasExpression(template, "<#list archiveDates as archiveDate>")) {
fillArchiveDates(dataModel, preference);
if (Templates.hasExpression(template, "<#list archiveDates as archiveDate>")) { }
fillArchiveDates(dataModel, preference);
} final String noticeBoard = preference.getString(Preference.NOTICE_BOARD);
dataModel.put(Preference.NOTICE_BOARD, noticeBoard);
final String noticeBoard = preference.getString(Preference.NOTICE_BOARD); } catch (final JSONException e) {
dataModel.put(Preference.NOTICE_BOARD, noticeBoard); LOGGER.log(Level.SEVERE, "Fills user template failed", e);
} catch (final JSONException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills user template failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Fills page navigations.
/** *
* Fills page navigations. * @param dataModel data model
* * @throws ServiceException service exception
* @param dataModel data model */
* @throws ServiceException service exception private void fillPageNavigations(final Map<String, Object> dataModel) throws ServiceException {
*/ Stopwatchs.start("Fill Navigations");
private void fillPageNavigations(final Map<String, Object> dataModel) throws ServiceException { try {
Stopwatchs.start("Fill Navigations"); LOGGER.finer("Filling page navigations....");
try { final List<JSONObject> pages = pageRepository.getPages();
LOGGER.finer("Filling page navigations....");
final List<JSONObject> pages = pageRepository.getPages(); for (final JSONObject page : pages) {
if ("page".equals(page.optString(Page.PAGE_TYPE))) {
for (final JSONObject page : pages) { final String permalink = page.optString(Page.PAGE_PERMALINK);
if ("page".equals(page.optString(Page.PAGE_TYPE))) { page.put(Page.PAGE_PERMALINK, Latkes.getServePath() + permalink);
final String permalink = page.optString(Page.PAGE_PERMALINK); }
page.put(Page.PAGE_PERMALINK, Latkes.getServePath() + permalink); }
}
} dataModel.put(Common.PAGE_NAVIGATIONS, pages);
} catch (final RepositoryException e) {
dataModel.put(Common.PAGE_NAVIGATIONS, pages); LOGGER.log(Level.SEVERE, "Fills page navigations failed", e);
} catch (final RepositoryException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills page navigations failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Fills statistic.
/** *
* Fills statistic. * @param dataModel data model
* * @throws ServiceException service exception
* @param dataModel data model */
* @throws ServiceException service exception private void fillStatistic(final Map<String, Object> dataModel) throws ServiceException {
*/ Stopwatchs.start("Fill Statistic");
private void fillStatistic(final Map<String, Object> dataModel) throws ServiceException { try {
Stopwatchs.start("Fill Statistic"); LOGGER.finer("Filling statistic....");
try { final JSONObject statistic = statisticRepository.get(Statistic.STATISTIC);
LOGGER.finer("Filling statistic....");
final JSONObject statistic = statisticRepository.get(Statistic.STATISTIC); dataModel.put(Statistic.STATISTIC, statistic);
} catch (final RepositoryException e) {
dataModel.put(Statistic.STATISTIC, statistic); LOGGER.log(Level.SEVERE, "Fills statistic failed", e);
} catch (final RepositoryException e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Fills statistic failed", e); } finally {
throw new ServiceException(e); Stopwatchs.end();
} finally { }
Stopwatchs.end(); }
}
} /**
* Sets some extra properties into the specified article with the specified author and preference, performs content and
/** * abstract editor processing.
* Sets some extra properties into the specified article with the specified author and preference, performs content and *
* abstract editor processing. * <p>
* * Article ext properties:
* <p> * <pre>
* Article ext properties: * {
* <pre> * ....,
* { * "authorName": "",
* ...., * "authorId": "",
* "authorName": "", * "hasUpdated": boolean
* "authorId": "", * }
* "hasUpdated": boolean * </pre>
* } * </p>
* </pre> *
* </p> * @param article the specified article
* * @param author the specified author
* @param article the specified article * @param preference the specified preference
* @param author the specified author * @throws ServiceException service exception
* @param preference the specified preference * @see #setArticlesExProperties(java.util.List, org.json.JSONObject)
* @throws ServiceException service exception */
* @see #setArticlesExProperties(java.util.List, org.json.JSONObject) private void setArticleExProperties(final JSONObject article, final JSONObject author, final JSONObject preference)
*/ throws ServiceException {
private void setArticleExProperties(final JSONObject article, final JSONObject author, final JSONObject preference) try {
throws ServiceException { final String authorName = author.getString(User.USER_NAME);
try { article.put(Common.AUTHOR_NAME, authorName);
final String authorName = author.getString(User.USER_NAME); final String authorId = author.getString(Keys.OBJECT_ID);
article.put(Common.AUTHOR_NAME, authorName); article.put(Common.AUTHOR_ID, authorId);
final String authorId = author.getString(Keys.OBJECT_ID);
article.put(Common.AUTHOR_ID, authorId); if (preference.getBoolean(Preference.ENABLE_ARTICLE_UPDATE_HINT)) {
article.put(Common.HAS_UPDATED, articleUtils.hasUpdated(article));
if (preference.getBoolean(Preference.ENABLE_ARTICLE_UPDATE_HINT)) { } else {
article.put(Common.HAS_UPDATED, articleUtils.hasUpdated(article)); article.put(Common.HAS_UPDATED, false);
} else { }
article.put(Common.HAS_UPDATED, false);
} processArticleAbstract(preference, article);
processArticleAbstract(preference, article); articleQueryService.markdown(article);
} catch (final Exception e) {
articleQueryService.markdown(article); LOGGER.log(Level.SEVERE, "Sets article extra properties failed", e);
} catch (final Exception e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Sets article extra properties failed", e); }
throw new ServiceException(e); }
}
} /**
* Sets some extra properties into the specified article with the specified preference, performs content and
/** * abstract editor processing.
* Sets some extra properties into the specified article with the specified preference, performs content and *
* abstract editor processing. * <p>
* * Article ext properties:
* <p> * <pre>
* Article ext properties: * {
* <pre> * ....,
* { * "authorName": "",
* ...., * "authorId": "",
* "authorName": "", * "hasUpdated": boolean
* "authorId": "", * }
* "hasUpdated": boolean * </pre>
* } * </p>
* </pre> *
* </p> * @param article the specified article
* * @param preference the specified preference
* @param article the specified article * @throws ServiceException service exception
* @param preference the specified preference * @see #setArticlesExProperties(java.util.List, org.json.JSONObject)
* @throws ServiceException service exception */
* @see #setArticlesExProperties(java.util.List, org.json.JSONObject) private void setArticleExProperties(final JSONObject article, final JSONObject preference) throws ServiceException {
*/ try {
private void setArticleExProperties(final JSONObject article, final JSONObject preference) throws ServiceException { final JSONObject author = articleUtils.getAuthor(article);
try { final String authorName = author.getString(User.USER_NAME);
final JSONObject author = articleUtils.getAuthor(article); article.put(Common.AUTHOR_NAME, authorName);
final String authorName = author.getString(User.USER_NAME); final String authorId = author.getString(Keys.OBJECT_ID);
article.put(Common.AUTHOR_NAME, authorName); article.put(Common.AUTHOR_ID, authorId);
final String authorId = author.getString(Keys.OBJECT_ID);
article.put(Common.AUTHOR_ID, authorId); if (preference.getBoolean(Preference.ENABLE_ARTICLE_UPDATE_HINT)) {
article.put(Common.HAS_UPDATED, articleUtils.hasUpdated(article));
if (preference.getBoolean(Preference.ENABLE_ARTICLE_UPDATE_HINT)) { } else {
article.put(Common.HAS_UPDATED, articleUtils.hasUpdated(article)); article.put(Common.HAS_UPDATED, false);
} else { }
article.put(Common.HAS_UPDATED, false);
} processArticleAbstract(preference, article);
processArticleAbstract(preference, article); articleQueryService.markdown(article);
} catch (final Exception e) {
articleQueryService.markdown(article); LOGGER.log(Level.SEVERE, "Sets article extra properties failed", e);
} catch (final Exception e) { throw new ServiceException(e);
LOGGER.log(Level.SEVERE, "Sets article extra properties failed", e); }
throw new ServiceException(e); }
}
} /**
* Sets some extra properties into the specified article with the specified
/** * author and preference.
* Sets some extra properties into the specified article with the specified *
* author and preference. * <p>
* * The batch version of method
* <p> * {@linkplain #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)}.
* The batch version of method * </p>
* {@linkplain #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)}. *
* </p> * <p>
* * Article ext properties:
* <p> * <pre>
* Article ext properties: * {
* <pre> * ....,
* { * "authorName": "",
* ...., * "authorId": "",
* "authorName": "", * "hasUpdated": boolean
* "authorId": "", * }
* "hasUpdated": boolean * </pre>
* } * </p>
* </pre> *
* </p> * @param articles the specified articles
* * @param author the specified author
* @param articles the specified articles * @param preference the specified preference
* @param author the specified author * @throws ServiceException service exception
* @param preference the specified preference * @see #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)
* @throws ServiceException service exception */
* @see #setArticleExProperties(org.json.JSONObject, org.json.JSONObject) public void setArticlesExProperties(final List<JSONObject> articles, final JSONObject author, final JSONObject preference)
*/ throws ServiceException {
public void setArticlesExProperties(final List<JSONObject> articles, final JSONObject author, final JSONObject preference) for (final JSONObject article : articles) {
throws ServiceException { setArticleExProperties(article, author, preference);
for (final JSONObject article : articles) { }
setArticleExProperties(article, author, preference); }
}
} /**
* Sets some extra properties into the specified article with the specified
/** * preference.
* Sets some extra properties into the specified article with the specified *
* preference. * <p>
* * The batch version of method
* <p> * {@linkplain #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)}.
* The batch version of method * </p>
* {@linkplain #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)}. *
* </p> * <p>
* * Article ext properties:
* <p> * <pre>
* Article ext properties: * {
* <pre> * ....,
* { * "authorName": "",
* ...., * "authorId": "",
* "authorName": "", * "hasUpdated": boolean
* "authorId": "", * }
* "hasUpdated": boolean * </pre>
* } * </p>
* </pre> *
* </p> * @param articles the specified articles
* * @param preference the specified preference
* @param articles the specified articles * @throws ServiceException service exception
* @param preference the specified preference * @see #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)
* @throws ServiceException service exception */
* @see #setArticleExProperties(org.json.JSONObject, org.json.JSONObject) public void setArticlesExProperties(final List<JSONObject> articles, final JSONObject preference)
*/ throws ServiceException {
public void setArticlesExProperties(final List<JSONObject> articles, final JSONObject preference) for (final JSONObject article : articles) {
throws ServiceException { setArticleExProperties(article, preference);
for (final JSONObject article : articles) { }
setArticleExProperties(article, preference); }
}
} /**
* Processes the abstract of the specified article with the specified preference.
/** *
* Processes the abstract of the specified article with the specified preference. * <p>
* * <ul>
* <p> * <li>If the abstract is {@code null}, sets it with ""</li>
* <ul> * <li>If user configured preference "titleOnly", sets the abstract with ""</li>
* <li>If the abstract is {@code null}, sets it with ""</li> * <li>If user configured preference "titleAndContent", sets the abstract with the content of the article</li>
* <li>If user configured preference "titleOnly", sets the abstract with ""</li> * </ul>
* <li>If user configured preference "titleAndContent", sets the abstract with the content of the article</li> * </p>
* </ul> *
* </p> * @param preference the specified preference
* * @param article the specified article
* @param preference the specified preference */
* @param article the specified article private void processArticleAbstract(final JSONObject preference, final JSONObject article) {
*/ final String articleAbstract = article.optString(Article.ARTICLE_ABSTRACT, null);
private void processArticleAbstract(final JSONObject preference, final JSONObject article) { if (null == articleAbstract) {
final String articleAbstract = article.optString(Article.ARTICLE_ABSTRACT, null); article.put(Article.ARTICLE_ABSTRACT, "");
if (null == articleAbstract) { }
article.put(Article.ARTICLE_ABSTRACT, "");
} final String articleListStyle = preference.optString(Preference.ARTICLE_LIST_STYLE);
if ("titleOnly".equals(articleListStyle)) {
final String articleListStyle = preference.optString(Preference.ARTICLE_LIST_STYLE); article.put(Article.ARTICLE_ABSTRACT, "");
if ("titleOnly".equals(articleListStyle)) { } else if ("titleAndContent".equals(articleListStyle)) {
article.put(Article.ARTICLE_ABSTRACT, ""); article.put(Article.ARTICLE_ABSTRACT, article.optString(Article.ARTICLE_CONTENT));
} else if ("titleAndContent".equals(articleListStyle)) { }
article.put(Article.ARTICLE_ABSTRACT, article.optString(Article.ARTICLE_CONTENT)); }
}
} /**
* Gets the {@link Filler} singleton.
/** *
* Gets the {@link Filler} singleton. * @return the singleton
* */
* @return the singleton public static Filler getInstance() {
*/ return SingletonHolder.SINGLETON;
public static Filler getInstance() { }
return SingletonHolder.SINGLETON;
} /**
* Private default constructor.
/** */
* Private default constructor. private Filler() {
*/ }
private Filler() {
} /**
* Singleton holder.
/** *
* Singleton holder. * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* * @version 1.0.0.0, Jan 12, 2011
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> */
* @version 1.0.0.0, Jan 12, 2011 private static final class SingletonHolder {
*/
private static final class SingletonHolder { /**
* Singleton.
/** */
* Singleton. private static final Filler SINGLETON = new Filler();
*/
private static final Filler SINGLETON = new Filler(); /**
* Private default constructor.
/** */
* Private default constructor. private SingletonHolder() {
*/ }
private SingletonHolder() { }
} }
}
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.repository.impl; package org.b3log.solo.repository.impl;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.repository.AbstractRepository; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.FilterOperator; import org.b3log.solo.model.Article;
import org.b3log.latke.repository.Query; import org.b3log.solo.model.ArchiveDate;
import org.b3log.solo.model.Article; import org.b3log.solo.repository.ArchiveDateArticleRepository;
import org.b3log.latke.repository.RepositoryException; import org.json.JSONArray;
import org.b3log.latke.repository.SortDirection; import org.json.JSONObject;
import org.b3log.solo.model.ArchiveDate;
import org.b3log.solo.repository.ArchiveDateArticleRepository; /**
import org.json.JSONArray; * Archive date-Article relation repository.
import org.json.JSONObject; *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
/** * @version 1.0.0.6, Nov 9, 2011
* Archive date-Article relation repository. * @since 0.3.1
* */
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> public final class ArchiveDateArticleRepositoryImpl extends AbstractRepository implements ArchiveDateArticleRepository {
* @version 1.0.0.6, Nov 9, 2011
* @since 0.3.1 /**
*/ * Singleton.
public final class ArchiveDateArticleRepositoryImpl extends AbstractRepository implements ArchiveDateArticleRepository { */
private static final ArchiveDateArticleRepositoryImpl SINGLETON =
/** new ArchiveDateArticleRepositoryImpl(ArchiveDate.ARCHIVE_DATE + "_" + Article.ARTICLE);
* Singleton.
*/ @Override
private static final ArchiveDateArticleRepositoryImpl SINGLETON = public JSONObject getByArchiveDateId(final String archiveDateId, final int currentPageNum, final int pageSize)
new ArchiveDateArticleRepositoryImpl(ArchiveDate.ARCHIVE_DATE + "_" + Article.ARTICLE); throws RepositoryException {
final Query query = new Query().setFilter(new PropertyFilter(ArchiveDate.ARCHIVE_DATE + "_" + Keys.OBJECT_ID,
@Override FilterOperator.EQUAL, archiveDateId)).
public JSONObject getByArchiveDateId(final String archiveDateId, final int currentPageNum, final int pageSize) addSort(Article.ARTICLE + "_" + Keys.OBJECT_ID,
throws RepositoryException { SortDirection.DESCENDING).
final Query query = new Query().addFilter(ArchiveDate.ARCHIVE_DATE + "_" + Keys.OBJECT_ID, setCurrentPageNum(currentPageNum).
FilterOperator.EQUAL, archiveDateId). setPageSize(pageSize).
addSort(Article.ARTICLE + "_" + Keys.OBJECT_ID, setPageCount(1);
SortDirection.DESCENDING).
setCurrentPageNum(currentPageNum). return get(query);
setPageSize(pageSize). }
setPageCount(1);
@Override
return get(query); public JSONObject getByArticleId(final String articleId) throws RepositoryException {
} final Query query = new Query();
query.setFilter(new PropertyFilter(Article.ARTICLE + "_" + Keys.OBJECT_ID, FilterOperator.EQUAL, articleId));
@Override
public JSONObject getByArticleId(final String articleId) throws RepositoryException { final JSONObject result = get(query);
final Query query = new Query(); final JSONArray array = result.optJSONArray(Keys.RESULTS);
query.addFilter(Article.ARTICLE + "_" + Keys.OBJECT_ID, FilterOperator.EQUAL, articleId); if (0 == array.length()) {
return null;
final JSONObject result = get(query); }
final JSONArray array = result.optJSONArray(Keys.RESULTS);
if (0 == array.length()) { return array.optJSONObject(0);
return null; }
}
/**
return array.optJSONObject(0); * Gets the {@link ArchiveDateArticleRepositoryImpl} singleton.
} *
* @return the singleton
/** */
* Gets the {@link ArchiveDateArticleRepositoryImpl} singleton. public static ArchiveDateArticleRepositoryImpl getInstance() {
* return SINGLETON;
* @return the singleton }
*/
public static ArchiveDateArticleRepositoryImpl getInstance() { /**
return SINGLETON; * Private constructor.
} *
* @param name the specified name
/** */
* Private constructor. private ArchiveDateArticleRepositoryImpl(final String name) {
* super(name);
* @param name the specified name }
*/ }
private ArchiveDateArticleRepositoryImpl(final String name) {
super(name);
}
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.repository.impl; package org.b3log.solo.repository.impl;
import java.text.ParseException; import java.text.ParseException;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.repository.AbstractRepository; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.FilterOperator; import org.b3log.latke.util.CollectionUtils;
import org.b3log.latke.repository.Query; import org.b3log.solo.model.ArchiveDate;
import org.b3log.latke.repository.RepositoryException; import org.b3log.solo.repository.ArchiveDateRepository;
import org.b3log.latke.repository.SortDirection; import org.json.JSONArray;
import org.b3log.latke.util.CollectionUtils; import org.json.JSONObject;
import org.b3log.solo.model.ArchiveDate;
import org.b3log.solo.repository.ArchiveDateRepository; /**
import org.json.JSONArray; * Archive date repository.
import org.json.JSONObject; *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
/** * @version 1.0.0.6, Dec 31, 2011
* Archive date repository. * @since 0.3.1
* */
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> public final class ArchiveDateRepositoryImpl extends AbstractRepository implements ArchiveDateRepository {
* @version 1.0.0.6, Dec 31, 2011
* @since 0.3.1 /**
*/ * Logger.
public final class ArchiveDateRepositoryImpl extends AbstractRepository implements ArchiveDateRepository { */
private static final Logger LOGGER = Logger.getLogger(ArchiveDateRepositoryImpl.class.getName());
/** /**
* Logger. * Singleton.
*/ */
private static final Logger LOGGER = Logger.getLogger(ArchiveDateRepositoryImpl.class.getName()); private static final ArchiveDateRepositoryImpl SINGLETON = new ArchiveDateRepositoryImpl(ArchiveDate.ARCHIVE_DATE);
/**
* Singleton. @Override
*/ public JSONObject getByArchiveDate(final String archiveDate) throws RepositoryException {
private static final ArchiveDateRepositoryImpl SINGLETON = new ArchiveDateRepositoryImpl(ArchiveDate.ARCHIVE_DATE); long time = 0L;
try {
@Override time = ArchiveDate.DATE_FORMAT.parse(archiveDate).getTime();
public JSONObject getByArchiveDate(final String archiveDate) throws RepositoryException { } catch (final ParseException e) {
long time = 0L; LOGGER.log(Level.SEVERE, "Can not parse archive date [" + archiveDate + "]", e);
try { throw new RepositoryException("Can not parse archive date [" + archiveDate + "]");
time = ArchiveDate.DATE_FORMAT.parse(archiveDate).getTime(); }
} catch (final ParseException e) {
LOGGER.log(Level.SEVERE, "Can not parse archive date [" + archiveDate + "]", e); final Query query = new Query();
throw new RepositoryException("Can not parse archive date [" + archiveDate + "]"); query.setFilter(new PropertyFilter(ArchiveDate.ARCHIVE_TIME, FilterOperator.EQUAL, time)).setPageCount(1);
}
final JSONObject result = get(query);
final Query query = new Query(); final JSONArray array = result.optJSONArray(Keys.RESULTS);
query.addFilter(ArchiveDate.ARCHIVE_TIME, FilterOperator.EQUAL, time).setPageCount(1);
if (0 == array.length()) {
final JSONObject result = get(query); return null;
final JSONArray array = result.optJSONArray(Keys.RESULTS); }
if (0 == array.length()) { return array.optJSONObject(0);
return null; }
}
@Override
return array.optJSONObject(0); public List<JSONObject> getArchiveDates() throws RepositoryException {
} final org.b3log.latke.repository.Query query =
new Query().addSort(ArchiveDate.ARCHIVE_TIME, SortDirection.DESCENDING).setPageCount(1);
@Override final JSONObject result = get(query);
public List<JSONObject> getArchiveDates() throws RepositoryException {
final org.b3log.latke.repository.Query query = final JSONArray archiveDates = result.optJSONArray(Keys.RESULTS);
new Query().addSort(ArchiveDate.ARCHIVE_TIME, SortDirection.DESCENDING).setPageCount(1); final List<JSONObject> ret = CollectionUtils.jsonArrayToList(archiveDates);
final JSONObject result = get(query);
removeForUnpublishedArticles(ret);
final JSONArray archiveDates = result.optJSONArray(Keys.RESULTS);
final List<JSONObject> ret = CollectionUtils.jsonArrayToList(archiveDates); return ret;
}
removeForUnpublishedArticles(ret);
/**
return ret; * Removes archive dates of unpublished articles from the specified archive
} * dates.
*
/** * @param archiveDates the specified archive dates
* Removes archive dates of unpublished articles from the specified archive * @throws RepositoryException repository exception
* dates. */
* private void removeForUnpublishedArticles(final List<JSONObject> archiveDates) throws RepositoryException {
* @param archiveDates the specified archive dates final Iterator<JSONObject> iterator = archiveDates.iterator();
* @throws RepositoryException repository exception while (iterator.hasNext()) {
*/ final JSONObject archiveDate = iterator.next();
private void removeForUnpublishedArticles(final List<JSONObject> archiveDates) throws RepositoryException { if (0 == archiveDate.optInt(ArchiveDate.ARCHIVE_DATE_PUBLISHED_ARTICLE_COUNT)) {
final Iterator<JSONObject> iterator = archiveDates.iterator(); iterator.remove();
while (iterator.hasNext()) { }
final JSONObject archiveDate = iterator.next(); }
if (0 == archiveDate.optInt(ArchiveDate.ARCHIVE_DATE_PUBLISHED_ARTICLE_COUNT)) { }
iterator.remove();
} /**
} * Gets the {@link ArchiveDateRepositoryImpl} singleton.
} *
* @return the singleton
/** */
* Gets the {@link ArchiveDateRepositoryImpl} singleton. public static ArchiveDateRepositoryImpl getInstance() {
* return SINGLETON;
* @return the singleton }
*/
public static ArchiveDateRepositoryImpl getInstance() { /**
return SINGLETON; * Private constructor.
} *
* @param name the specified name
/** */
* Private constructor. private ArchiveDateRepositoryImpl(final String name) {
* super(name);
* @param name the specified name }
*/ }
private ArchiveDateRepositoryImpl(final String name) {
super(name);
}
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.repository.impl; package org.b3log.solo.repository.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.b3log.solo.model.Article; import org.b3log.solo.model.Article;
import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.repository.ArticleRepository;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.repository.*; import org.b3log.latke.repository.*;
import org.b3log.latke.util.CollectionUtils; import org.b3log.latke.util.CollectionUtils;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
/** /**
* Article repository. * Article repository.
* *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.3.9, May 8, 2012 * @version 1.0.3.9, May 8, 2012
* @since 0.3.1 * @since 0.3.1
*/ */
public final class ArticleRepositoryImpl extends AbstractRepository implements ArticleRepository { public final class ArticleRepositoryImpl extends AbstractRepository implements ArticleRepository {
/** /**
* Logger. * Logger.
*/ */
private static final Logger LOGGER = Logger.getLogger(ArticleRepositoryImpl.class.getName()); private static final Logger LOGGER = Logger.getLogger(ArticleRepositoryImpl.class.getName());
/** /**
* Singleton. * Singleton.
*/ */
private static final ArticleRepositoryImpl SINGLETON = new ArticleRepositoryImpl(Article.ARTICLE); private static final ArticleRepositoryImpl SINGLETON = new ArticleRepositoryImpl(Article.ARTICLE);
/** /**
* Random range. * Random range.
*/ */
private static final double RANDOM_RANGE = 0.1D; private static final double RANDOM_RANGE = 0.1D;
@Override @Override
public JSONObject getByAuthorEmail(final String authorEmail, final int currentPageNum, final int pageSize) public JSONObject getByAuthorEmail(final String authorEmail, final int currentPageNum, final int pageSize)
throws RepositoryException { throws RepositoryException {
final Query query = new Query().addFilter(Article.ARTICLE_AUTHOR_EMAIL, FilterOperator.EQUAL, authorEmail). final Query query = new Query().setFilter(CompositeFilterOperator.and(
addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true). new PropertyFilter(Article.ARTICLE_AUTHOR_EMAIL, FilterOperator.EQUAL, authorEmail),
addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING). new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true))).
setCurrentPageNum(currentPageNum).setPageSize(pageSize).setPageCount(1); addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING).
setCurrentPageNum(currentPageNum).setPageSize(pageSize).setPageCount(1);
return get(query);
} return get(query);
}
@Override
public JSONObject getByPermalink(final String permalink) throws RepositoryException { @Override
final Query query = new Query().addFilter(Article.ARTICLE_PERMALINK, FilterOperator.EQUAL, permalink). public JSONObject getByPermalink(final String permalink) throws RepositoryException {
setPageCount(1); final Query query = new Query().setFilter(
new PropertyFilter(Article.ARTICLE_PERMALINK, FilterOperator.EQUAL, permalink)).
final JSONObject result = get(query); setPageCount(1);
final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query);
if (0 == array.length()) { final JSONArray array = result.optJSONArray(Keys.RESULTS);
return null;
} if (0 == array.length()) {
return null;
return array.optJSONObject(0); }
}
return array.optJSONObject(0);
@Override }
public List<JSONObject> getRecentArticles(final int fetchSize) throws RepositoryException {
final Query query = new Query(); @Override
query.addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true); public List<JSONObject> getRecentArticles(final int fetchSize) throws RepositoryException {
query.addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING); final Query query = new Query();
query.setCurrentPageNum(1); query.setFilter(new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true));
query.setPageSize(fetchSize); query.addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING);
query.setPageCount(1); query.setCurrentPageNum(1);
query.setPageSize(fetchSize);
final JSONObject result = get(query); query.setPageCount(1);
final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query);
return CollectionUtils.jsonArrayToList(array); final JSONArray array = result.optJSONArray(Keys.RESULTS);
}
return CollectionUtils.jsonArrayToList(array);
@Override }
public List<JSONObject> getMostCommentArticles(final int num) throws RepositoryException {
final Query query = new Query().addSort(Article.ARTICLE_COMMENT_COUNT, SortDirection.DESCENDING). @Override
addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING). public List<JSONObject> getMostCommentArticles(final int num) throws RepositoryException {
addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true). final Query query = new Query().addSort(Article.ARTICLE_COMMENT_COUNT, SortDirection.DESCENDING).
setCurrentPageNum(1).setPageSize(num).setPageCount(1); addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING).
setFilter(new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true)).
final JSONObject result = get(query); setCurrentPageNum(1).setPageSize(num).setPageCount(1);
final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query);
return CollectionUtils.jsonArrayToList(array); final JSONArray array = result.optJSONArray(Keys.RESULTS);
}
return CollectionUtils.jsonArrayToList(array);
@Override }
public List<JSONObject> getMostViewCountArticles(final int num) throws RepositoryException {
final Query query = new Query(); @Override
query.addSort(Article.ARTICLE_VIEW_COUNT, SortDirection.DESCENDING). public List<JSONObject> getMostViewCountArticles(final int num) throws RepositoryException {
addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING); final Query query = new Query();
query.addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true); query.addSort(Article.ARTICLE_VIEW_COUNT, SortDirection.DESCENDING).
query.setCurrentPageNum(1); addSort(Article.ARTICLE_UPDATE_DATE, SortDirection.DESCENDING);
query.setPageSize(num); query.setFilter(new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true));
query.setPageCount(1); query.setCurrentPageNum(1);
query.setPageSize(num);
final JSONObject result = get(query); query.setPageCount(1);
final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query);
return CollectionUtils.jsonArrayToList(array); final JSONArray array = result.optJSONArray(Keys.RESULTS);
}
return CollectionUtils.jsonArrayToList(array);
@Override }
public JSONObject getPreviousArticle(final String articleId) throws RepositoryException {
final JSONObject currentArticle = get(articleId); @Override
final Date currentArticleCreateDate = (Date) currentArticle.opt(Article.ARTICLE_CREATE_DATE); public JSONObject getPreviousArticle(final String articleId) throws RepositoryException {
final JSONObject currentArticle = get(articleId);
final Query query = new Query().addFilter(Article.ARTICLE_CREATE_DATE, FilterOperator.LESS_THAN, currentArticleCreateDate). final Date currentArticleCreateDate = (Date) currentArticle.opt(Article.ARTICLE_CREATE_DATE);
addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true).
addSort(Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING).setCurrentPageNum(1). final Query query = new Query().setFilter(
setPageSize(1).setPageCount(1). CompositeFilterOperator.and(
addProjection(Article.ARTICLE_TITLE, String.class). new PropertyFilter(Article.ARTICLE_CREATE_DATE, FilterOperator.LESS_THAN, currentArticleCreateDate),
addProjection(Article.ARTICLE_PERMALINK, String.class); new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true))).
addSort(Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING).setCurrentPageNum(1).
final JSONObject result = get(query); setPageSize(1).setPageCount(1).
final JSONArray array = result.optJSONArray(Keys.RESULTS); addProjection(Article.ARTICLE_TITLE, String.class).
addProjection(Article.ARTICLE_PERMALINK, String.class);
if (1 != array.length()) {
return null; final JSONObject result = get(query);
} final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject ret = new JSONObject(); if (1 != array.length()) {
final JSONObject article = array.optJSONObject(0); return null;
}
try {
ret.put(Article.ARTICLE_TITLE, article.getString(Article.ARTICLE_TITLE)); final JSONObject ret = new JSONObject();
ret.put(Article.ARTICLE_PERMALINK, article.getString(Article.ARTICLE_PERMALINK)); final JSONObject article = array.optJSONObject(0);
} catch (final JSONException e) {
throw new RepositoryException(e); try {
} ret.put(Article.ARTICLE_TITLE, article.getString(Article.ARTICLE_TITLE));
ret.put(Article.ARTICLE_PERMALINK, article.getString(Article.ARTICLE_PERMALINK));
return ret; } catch (final JSONException e) {
} throw new RepositoryException(e);
}
@Override
public JSONObject getNextArticle(final String articleId) throws RepositoryException { return ret;
final JSONObject currentArticle = get(articleId); }
final Date currentArticleCreateDate = (Date) currentArticle.opt(Article.ARTICLE_CREATE_DATE);
@Override
final Query query = new Query().addFilter(Article.ARTICLE_CREATE_DATE, FilterOperator.GREATER_THAN, currentArticleCreateDate). public JSONObject getNextArticle(final String articleId) throws RepositoryException {
addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true). final JSONObject currentArticle = get(articleId);
addSort(Article.ARTICLE_CREATE_DATE, SortDirection.ASCENDING).setCurrentPageNum(1). final Date currentArticleCreateDate = (Date) currentArticle.opt(Article.ARTICLE_CREATE_DATE);
setPageSize(1).setPageCount(1).
addProjection(Article.ARTICLE_TITLE, String.class). final Query query = new Query().setFilter(
addProjection(Article.ARTICLE_PERMALINK, String.class); CompositeFilterOperator.and(
new PropertyFilter(Article.ARTICLE_CREATE_DATE, FilterOperator.GREATER_THAN, currentArticleCreateDate),
final JSONObject result = get(query); new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true))).
final JSONArray array = result.optJSONArray(Keys.RESULTS); addSort(Article.ARTICLE_CREATE_DATE, SortDirection.ASCENDING).setCurrentPageNum(1).
setPageSize(1).setPageCount(1).
if (1 != array.length()) { addProjection(Article.ARTICLE_TITLE, String.class).
return null; addProjection(Article.ARTICLE_PERMALINK, String.class);
}
final JSONObject result = get(query);
final JSONObject ret = new JSONObject(); final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject article = array.optJSONObject(0);
if (1 != array.length()) {
try { return null;
ret.put(Article.ARTICLE_TITLE, article.getString(Article.ARTICLE_TITLE)); }
ret.put(Article.ARTICLE_PERMALINK, article.getString(Article.ARTICLE_PERMALINK));
} catch (final JSONException e) { final JSONObject ret = new JSONObject();
throw new RepositoryException(e); final JSONObject article = array.optJSONObject(0);
}
try {
return ret; ret.put(Article.ARTICLE_TITLE, article.getString(Article.ARTICLE_TITLE));
} ret.put(Article.ARTICLE_PERMALINK, article.getString(Article.ARTICLE_PERMALINK));
} catch (final JSONException e) {
@Override throw new RepositoryException(e);
public boolean isPublished(final String articleId) throws RepositoryException { }
final JSONObject article = get(articleId);
if (null == article) { return ret;
return false; }
}
@Override
return article.optBoolean(Article.ARTICLE_IS_PUBLISHED); public boolean isPublished(final String articleId) throws RepositoryException {
} final JSONObject article = get(articleId);
if (null == article) {
@Override return false;
public List<JSONObject> getRandomly(final int fetchSize) throws RepositoryException { }
final List<JSONObject> ret = new ArrayList<JSONObject>();
return article.optBoolean(Article.ARTICLE_IS_PUBLISHED);
if (0 == count()) { }
return ret;
} @Override
public List<JSONObject> getRandomly(final int fetchSize) throws RepositoryException {
final double mid = Math.random() + RANDOM_RANGE; final List<JSONObject> ret = new ArrayList<JSONObject>();
LOGGER.log(Level.FINEST, "Random mid[{0}]", mid);
if (0 == count()) {
Query query = new Query(); return ret;
query.addFilter(Article.ARTICLE_RANDOM_DOUBLE, FilterOperator.GREATER_THAN_OR_EQUAL, mid); }
query.addFilter(Article.ARTICLE_RANDOM_DOUBLE, FilterOperator.LESS_THAN_OR_EQUAL, mid);
query.addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true); final double mid = Math.random() + RANDOM_RANGE;
query.setCurrentPageNum(1); LOGGER.log(Level.FINEST, "Random mid[{0}]", mid);
query.setPageSize(fetchSize);
query.setPageCount(1); Query query = new Query();
query.setFilter(CompositeFilterOperator.and(
final JSONObject result1 = get(query); new PropertyFilter(Article.ARTICLE_RANDOM_DOUBLE, FilterOperator.GREATER_THAN_OR_EQUAL, mid),
final JSONArray array1 = result1.optJSONArray(Keys.RESULTS); new PropertyFilter(Article.ARTICLE_RANDOM_DOUBLE, FilterOperator.LESS_THAN_OR_EQUAL, mid),
new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true)));
final List<JSONObject> list1 = CollectionUtils.<JSONObject>jsonArrayToList(array1); query.setCurrentPageNum(1);
ret.addAll(list1); query.setPageSize(fetchSize);
query.setPageCount(1);
final int reminingSize = fetchSize - array1.length();
if (0 != reminingSize) { // Query for remains final JSONObject result1 = get(query);
query = new Query(); final JSONArray array1 = result1.optJSONArray(Keys.RESULTS);
query.addFilter(Article.ARTICLE_RANDOM_DOUBLE, FilterOperator.GREATER_THAN_OR_EQUAL, 0D);
query.addFilter(Article.ARTICLE_RANDOM_DOUBLE, FilterOperator.LESS_THAN_OR_EQUAL, mid); final List<JSONObject> list1 = CollectionUtils.<JSONObject>jsonArrayToList(array1);
query.addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true); ret.addAll(list1);
query.setCurrentPageNum(1);
query.setPageSize(reminingSize); final int reminingSize = fetchSize - array1.length();
query.setPageCount(1); if (0 != reminingSize) { // Query for remains
query = new Query();
final JSONObject result2 = get(query); query.setFilter(CompositeFilterOperator.and(
final JSONArray array2 = result2.optJSONArray(Keys.RESULTS); new PropertyFilter(Article.ARTICLE_RANDOM_DOUBLE, FilterOperator.GREATER_THAN_OR_EQUAL, 0D),
new PropertyFilter(Article.ARTICLE_RANDOM_DOUBLE, FilterOperator.LESS_THAN_OR_EQUAL, mid),
final List<JSONObject> list2 = CollectionUtils.<JSONObject>jsonArrayToList(array2); new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true)));
ret.addAll(list2); query.setCurrentPageNum(1);
} query.setPageSize(reminingSize);
query.setPageCount(1);
return ret;
} final JSONObject result2 = get(query);
final JSONArray array2 = result2.optJSONArray(Keys.RESULTS);
/**
* Gets the {@link ArticleRepositoryImpl} singleton. final List<JSONObject> list2 = CollectionUtils.<JSONObject>jsonArrayToList(array2);
* ret.addAll(list2);
* @return the singleton }
*/
public static ArticleRepositoryImpl getInstance() { return ret;
return SINGLETON; }
}
/**
/** * Gets the {@link ArticleRepositoryImpl} singleton.
* Private constructor. *
* * @return the singleton
* @param name the specified name */
*/ public static ArticleRepositoryImpl getInstance() {
private ArticleRepositoryImpl(final String name) { return SINGLETON;
super(name); }
}
} /**
* Private constructor.
*
* @param name the specified name
*/
private ArticleRepositoryImpl(final String name) {
super(name);
}
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.repository.impl; package org.b3log.solo.repository.impl;
import java.io.Serializable; import java.io.Serializable;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.cache.Cache; import org.b3log.latke.cache.Cache;
import org.b3log.latke.repository.AbstractRepository; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.FilterOperator; import org.b3log.solo.model.Comment;
import org.b3log.latke.repository.Query; import org.b3log.solo.repository.CommentRepository;
import org.b3log.latke.repository.RepositoryException; import org.b3log.latke.util.CollectionUtils;
import org.b3log.latke.repository.SortDirection; import org.b3log.solo.model.Article;
import org.b3log.solo.model.Comment; import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.CommentRepository; import org.json.JSONArray;
import org.b3log.latke.util.CollectionUtils; import org.json.JSONObject;
import org.b3log.solo.model.Article;
import org.b3log.solo.repository.ArticleRepository; /**
import org.json.JSONArray; * Comment repository.
import org.json.JSONObject; *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
/** * @version 1.0.0.8, Oct 18, 2011
* Comment repository. * @since 0.3.1
* */
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> public final class CommentRepositoryImpl extends AbstractRepository implements CommentRepository {
* @version 1.0.0.8, Oct 18, 2011
* @since 0.3.1 /**
*/ * Logger.
public final class CommentRepositoryImpl extends AbstractRepository implements CommentRepository { */
private static final Logger LOGGER = Logger.getLogger(CommentRepositoryImpl.class.getName());
/** /**
* Logger. * Singleton.
*/ */
private static final Logger LOGGER = Logger.getLogger(CommentRepositoryImpl.class.getName()); private static final CommentRepositoryImpl SINGLETON = new CommentRepositoryImpl(Comment.COMMENT);
/** /**
* Singleton. * Article repository.
*/ */
private static final CommentRepositoryImpl SINGLETON = new CommentRepositoryImpl(Comment.COMMENT); private ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance();
/** /**
* Article repository. * Recent comments query results cache key.
*/ */
private ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance(); public static final String RECENT_CMTS_CACHE_KEY = "recentCMTs";
/**
* Recent comments query results cache key. @Override
*/ public int removeComments(final String onId) throws RepositoryException {
public static final String RECENT_CMTS_CACHE_KEY = "recentCMTs"; final List<JSONObject> comments = getComments(onId, 1, Integer.MAX_VALUE);
@Override for (final JSONObject comment : comments) {
public int removeComments(final String onId) throws RepositoryException { final String commentId = comment.optString(Keys.OBJECT_ID);
final List<JSONObject> comments = getComments(onId, 1, Integer.MAX_VALUE); remove(commentId);
}
for (final JSONObject comment : comments) {
final String commentId = comment.optString(Keys.OBJECT_ID); LOGGER.log(Level.FINER, "Removed comments[onId={0}, removedCnt={1}]", new Object[]{onId, comments.size()});
remove(commentId);
} return comments.size();
}
LOGGER.log(Level.FINER, "Removed comments[onId={0}, removedCnt={1}]", new Object[]{onId, comments.size()});
@Override
return comments.size(); public List<JSONObject> getComments(final String onId, final int currentPageNum, final int pageSize)
} throws RepositoryException {
final Query query = new Query().addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).
@Override setFilter(new PropertyFilter(Comment.COMMENT_ON_ID, FilterOperator.EQUAL, onId)).
public List<JSONObject> getComments(final String onId, final int currentPageNum, final int pageSize) setCurrentPageNum(currentPageNum).
throws RepositoryException { setPageSize(pageSize).
final Query query = new Query().addSort(Keys.OBJECT_ID, SortDirection.DESCENDING). setPageCount(1);
addFilter(Comment.COMMENT_ON_ID, FilterOperator.EQUAL, onId).
setCurrentPageNum(currentPageNum). final JSONObject result = get(query);
setPageSize(pageSize).
setPageCount(1); final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query); return CollectionUtils.jsonArrayToList(array);
}
final JSONArray array = result.optJSONArray(Keys.RESULTS);
@Override
return CollectionUtils.jsonArrayToList(array); @SuppressWarnings("unchecked")
} public List<JSONObject> getRecentComments(final int num) throws RepositoryException {
if (isCacheEnabled()) {
@Override final Cache<String, Serializable> cache = getCache();
@SuppressWarnings("unchecked") final Object ret = cache.get(RECENT_CMTS_CACHE_KEY);
public List<JSONObject> getRecentComments(final int num) throws RepositoryException { if (null != ret) {
if (isCacheEnabled()) { return (List<JSONObject>) ret;
final Cache<String, Serializable> cache = getCache(); }
final Object ret = cache.get(RECENT_CMTS_CACHE_KEY); }
if (null != ret) {
return (List<JSONObject>) ret; final Query query = new Query().addSort(Keys.OBJECT_ID, SortDirection.DESCENDING).
} setCurrentPageNum(1).
} setPageSize(num).setPageCount(1);
final Query query = new Query().addSort(Keys.OBJECT_ID, SortDirection.DESCENDING). List<JSONObject> ret;
setCurrentPageNum(1). final JSONObject result = get(query);
setPageSize(num).setPageCount(1);
final JSONArray array = result.optJSONArray(Keys.RESULTS);
List<JSONObject> ret;
final JSONObject result = get(query); ret = CollectionUtils.jsonArrayToList(array);
final JSONArray array = result.optJSONArray(Keys.RESULTS); // Removes unpublished article related comments
removeForUnpublishedArticles(ret);
ret = CollectionUtils.jsonArrayToList(array);
if (isCacheEnabled()) {
// Removes unpublished article related comments final Cache<String, Serializable> cache = getCache();
removeForUnpublishedArticles(ret); cache.put(RECENT_CMTS_CACHE_KEY, (Serializable) ret);
}
if (isCacheEnabled()) {
final Cache<String, Serializable> cache = getCache(); return ret;
cache.put(RECENT_CMTS_CACHE_KEY, (Serializable) ret); }
}
/**
return ret; * Removes comments of unpublished articles for the specified comments.
} *
* @param comments the specified comments
/** * @throws RepositoryException repository exception
* Removes comments of unpublished articles for the specified comments. */
* private void removeForUnpublishedArticles(final List<JSONObject> comments) throws RepositoryException {
* @param comments the specified comments LOGGER.finer("Removing unpublished articles' comments....");
* @throws RepositoryException repository exception final Iterator<JSONObject> iterator = comments.iterator();
*/ while (iterator.hasNext()) {
private void removeForUnpublishedArticles(final List<JSONObject> comments) throws RepositoryException { final JSONObject comment = iterator.next();
LOGGER.finer("Removing unpublished articles' comments...."); final String commentOnType = comment.optString(Comment.COMMENT_ON_TYPE);
final Iterator<JSONObject> iterator = comments.iterator(); if (Article.ARTICLE.equals(commentOnType)) {
while (iterator.hasNext()) { final String articleId = comment.optString(Comment.COMMENT_ON_ID);
final JSONObject comment = iterator.next();
final String commentOnType = comment.optString(Comment.COMMENT_ON_TYPE); if (!articleRepository.isPublished(articleId)) {
if (Article.ARTICLE.equals(commentOnType)) { iterator.remove();
final String articleId = comment.optString(Comment.COMMENT_ON_ID); }
}
if (!articleRepository.isPublished(articleId)) { }
iterator.remove();
} LOGGER.finer("Removed unpublished articles' comments....");
} }
}
/**
LOGGER.finer("Removed unpublished articles' comments...."); * Gets the {@link CommentRepositoryImpl} singleton.
} *
* @return the singleton
/** */
* Gets the {@link CommentRepositoryImpl} singleton. public static CommentRepositoryImpl getInstance() {
* return SINGLETON;
* @return the singleton }
*/
public static CommentRepositoryImpl getInstance() { /**
return SINGLETON; * Private constructor.
} *
* @param name the specified name
/** */
* Private constructor. private CommentRepositoryImpl(final String name) {
* super(name);
* @param name the specified name }
*/ }
private CommentRepositoryImpl(final String name) {
super(name);
}
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.repository.impl; package org.b3log.solo.repository.impl;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.repository.AbstractRepository; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.FilterOperator; import org.b3log.solo.model.Link;
import org.b3log.latke.repository.Query; import org.b3log.solo.repository.LinkRepository;
import org.b3log.latke.repository.RepositoryException; import org.json.JSONArray;
import org.b3log.latke.repository.SortDirection; import org.json.JSONObject;
import org.b3log.solo.model.Link;
import org.b3log.solo.repository.LinkRepository; /**
import org.json.JSONArray; * Link repository.
import org.json.JSONObject; *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
/** * @version 1.0.0.5, Nov 10, 2011
* Link repository. * @since 0.3.1
* */
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> public final class LinkRepositoryImpl extends AbstractRepository implements LinkRepository {
* @version 1.0.0.5, Nov 10, 2011
* @since 0.3.1 /**
*/ * Logger.
public final class LinkRepositoryImpl extends AbstractRepository implements LinkRepository { */
private static final Logger LOGGER = Logger.getLogger(LinkRepositoryImpl.class.getName());
/** /**
* Logger. * Singleton.
*/ */
private static final Logger LOGGER = Logger.getLogger(LinkRepositoryImpl.class.getName()); private static final LinkRepositoryImpl SINGLETON = new LinkRepositoryImpl(Link.LINK);
/**
* Singleton. @Override
*/ public JSONObject getByAddress(final String address) throws RepositoryException {
private static final LinkRepositoryImpl SINGLETON = new LinkRepositoryImpl(Link.LINK); final Query query = new Query().setFilter(
new PropertyFilter(Link.LINK_ADDRESS, FilterOperator.EQUAL, address)).
@Override setPageCount(1);
public JSONObject getByAddress(final String address) throws RepositoryException {
final Query query = new Query().addFilter(Link.LINK_ADDRESS, FilterOperator.EQUAL, address). final JSONObject result = get(query);
setPageCount(1); final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query); if (0 == array.length()) {
final JSONArray array = result.optJSONArray(Keys.RESULTS); return null;
}
if (0 == array.length()) {
return null; return array.optJSONObject(0);
} }
return array.optJSONObject(0); @Override
} public int getMaxOrder() throws RepositoryException {
final Query query = new Query();
@Override query.addSort(Link.LINK_ORDER, SortDirection.DESCENDING);
public int getMaxOrder() throws RepositoryException {
final Query query = new Query(); final JSONObject result = get(query);
query.addSort(Link.LINK_ORDER, SortDirection.DESCENDING); final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query); if (0 == array.length()) {
final JSONArray array = result.optJSONArray(Keys.RESULTS); return -1;
}
if (0 == array.length()) {
return -1; return array.optJSONObject(0).optInt(Link.LINK_ORDER);
} }
return array.optJSONObject(0).optInt(Link.LINK_ORDER); @Override
} public JSONObject getByOrder(final int order) throws RepositoryException {
final Query query = new Query();
@Override query.setFilter(new PropertyFilter(Link.LINK_ORDER, FilterOperator.EQUAL, order));
public JSONObject getByOrder(final int order) throws RepositoryException {
final Query query = new Query(); final JSONObject result = get(query);
query.addFilter(Link.LINK_ORDER, FilterOperator.EQUAL, order); final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query); if (0 == array.length()) {
final JSONArray array = result.optJSONArray(Keys.RESULTS); return null;
}
if (0 == array.length()) {
return null; return array.optJSONObject(0);
} }
return array.optJSONObject(0); @Override
} public JSONObject getUpper(final String id) throws RepositoryException {
final JSONObject link = get(id);
@Override if (null == link) {
public JSONObject getUpper(final String id) throws RepositoryException { return null;
final JSONObject link = get(id); }
if (null == link) {
return null; final Query query = new Query();
} query.setFilter(
new PropertyFilter(Link.LINK_ORDER, FilterOperator.LESS_THAN, link.optInt(Link.LINK_ORDER))).
final Query query = new Query(); addSort(Link.LINK_ORDER, SortDirection.DESCENDING);
query.addFilter(Link.LINK_ORDER, FilterOperator.LESS_THAN, link.optInt(Link.LINK_ORDER)). query.setCurrentPageNum(1);
addSort(Link.LINK_ORDER, SortDirection.DESCENDING); query.setPageSize(1);
query.setCurrentPageNum(1);
query.setPageSize(1); final JSONObject result = get(query);
final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query);
final JSONArray array = result.optJSONArray(Keys.RESULTS); if (1 != array.length()) {
return null;
if (1 != array.length()) { }
return null;
} return array.optJSONObject(0);
}
return array.optJSONObject(0);
} @Override
public JSONObject getUnder(final String id) throws RepositoryException {
@Override final JSONObject link = get(id);
public JSONObject getUnder(final String id) throws RepositoryException { if (null == link) {
final JSONObject link = get(id); return null;
if (null == link) { }
return null;
} final Query query = new Query();
query.setFilter(new PropertyFilter(Link.LINK_ORDER, FilterOperator.GREATER_THAN, link.optInt(Link.LINK_ORDER))).
final Query query = new Query(); addSort(Link.LINK_ORDER, SortDirection.ASCENDING);
query.addFilter(Link.LINK_ORDER, FilterOperator.GREATER_THAN, link.optInt(Link.LINK_ORDER)). query.setCurrentPageNum(1);
addSort(Link.LINK_ORDER, SortDirection.ASCENDING); query.setPageSize(1);
query.setCurrentPageNum(1);
query.setPageSize(1); final JSONObject result = get(query);
final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query);
final JSONArray array = result.optJSONArray(Keys.RESULTS); if (1 != array.length()) {
return null;
if (1 != array.length()) { }
return null;
} return array.optJSONObject(0);
}
return array.optJSONObject(0);
} /**
* Gets the {@link LinkRepositoryImpl} singleton.
/** *
* Gets the {@link LinkRepositoryImpl} singleton. * @return the singleton
* */
* @return the singleton public static LinkRepositoryImpl getInstance() {
*/ return SINGLETON;
public static LinkRepositoryImpl getInstance() { }
return SINGLETON;
} /**
* Private constructor.
/** *
* Private constructor. * @param name the specified name
* */
* @param name the specified name private LinkRepositoryImpl(final String name) {
*/ super(name);
private LinkRepositoryImpl(final String name) { }
super(name); }
}
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.repository.impl; package org.b3log.solo.repository.impl;
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.repository.AbstractRepository; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.FilterOperator; import org.b3log.latke.util.CollectionUtils;
import org.b3log.latke.repository.Query; import org.b3log.solo.model.Page;
import org.b3log.latke.repository.RepositoryException; import org.b3log.solo.repository.PageRepository;
import org.b3log.latke.repository.SortDirection; import org.json.JSONArray;
import org.b3log.latke.util.CollectionUtils; import org.json.JSONObject;
import org.b3log.solo.model.Page;
import org.b3log.solo.repository.PageRepository; /**
import org.json.JSONArray; * Page repository.
import org.json.JSONObject; *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
/** * @version 1.0.0.9, Dec 31, 2011
* Page repository. * @since 0.3.1
* */
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> public final class PageRepositoryImpl extends AbstractRepository implements PageRepository {
* @version 1.0.0.9, Dec 31, 2011
* @since 0.3.1 /**
*/ * Logger.
public final class PageRepositoryImpl extends AbstractRepository implements PageRepository { */
private static final Logger LOGGER = Logger.getLogger(PageRepositoryImpl.class.getName());
/** /**
* Logger. * Singleton.
*/ */
private static final Logger LOGGER = Logger.getLogger(PageRepositoryImpl.class.getName()); private static final PageRepositoryImpl SINGLETON = new PageRepositoryImpl(Page.PAGE);
/**
* Singleton. @Override
*/ public JSONObject getByPermalink(final String permalink) throws RepositoryException {
private static final PageRepositoryImpl SINGLETON = new PageRepositoryImpl(Page.PAGE); final Query query = new Query().setFilter(
new PropertyFilter(Page.PAGE_PERMALINK, FilterOperator.EQUAL, permalink)).
@Override setPageCount(1);
public JSONObject getByPermalink(final String permalink) throws RepositoryException { final JSONObject result = get(query);
final Query query = new Query().addFilter(Page.PAGE_PERMALINK, FilterOperator.EQUAL, permalink). final JSONArray array = result.optJSONArray(Keys.RESULTS);
setPageCount(1);
final JSONObject result = get(query); if (0 == array.length()) {
final JSONArray array = result.optJSONArray(Keys.RESULTS); return null;
}
if (0 == array.length()) {
return null; return array.optJSONObject(0);
} }
return array.optJSONObject(0); @Override
} public int getMaxOrder() throws RepositoryException {
final Query query = new Query().addSort(Page.PAGE_ORDER, SortDirection.DESCENDING).
@Override setPageCount(1);
public int getMaxOrder() throws RepositoryException { final JSONObject result = get(query);
final Query query = new Query().addSort(Page.PAGE_ORDER, SortDirection.DESCENDING). final JSONArray array = result.optJSONArray(Keys.RESULTS);
setPageCount(1);
final JSONObject result = get(query); if (0 == array.length()) {
final JSONArray array = result.optJSONArray(Keys.RESULTS); return -1;
}
if (0 == array.length()) {
return -1; return array.optJSONObject(0).optInt(Page.PAGE_ORDER);
} }
return array.optJSONObject(0).optInt(Page.PAGE_ORDER); @Override
} public JSONObject getUpper(final String id) throws RepositoryException {
final JSONObject page = get(id);
@Override if (null == page) {
public JSONObject getUpper(final String id) throws RepositoryException { return null;
final JSONObject page = get(id); }
if (null == page) {
return null; final Query query = new Query().setFilter(
} new PropertyFilter(Page.PAGE_ORDER, FilterOperator.LESS_THAN, page.optInt(Page.PAGE_ORDER))).
addSort(Page.PAGE_ORDER, SortDirection.DESCENDING).
final Query query = new Query().addFilter(Page.PAGE_ORDER, FilterOperator.LESS_THAN, page.optInt(Page.PAGE_ORDER)). setCurrentPageNum(1).setPageSize(1).setPageCount(1);
addSort(Page.PAGE_ORDER, SortDirection.DESCENDING).
setCurrentPageNum(1).setPageSize(1).setPageCount(1); final JSONObject result = get(query);
final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query);
final JSONArray array = result.optJSONArray(Keys.RESULTS); if (1 != array.length()) {
return null;
if (1 != array.length()) { }
return null;
} return array.optJSONObject(0);
}
return array.optJSONObject(0);
} @Override
public JSONObject getUnder(final String id) throws RepositoryException {
@Override final JSONObject page = get(id);
public JSONObject getUnder(final String id) throws RepositoryException { if (null == page) {
final JSONObject page = get(id); return null;
if (null == page) { }
return null;
} final Query query = new Query().setFilter(
new PropertyFilter(Page.PAGE_ORDER, FilterOperator.GREATER_THAN, page.optInt(Page.PAGE_ORDER))).
final Query query = new Query().addFilter(Page.PAGE_ORDER, FilterOperator.GREATER_THAN, page.optInt(Page.PAGE_ORDER)). addSort(Page.PAGE_ORDER, SortDirection.ASCENDING).setCurrentPageNum(1).
addSort(Page.PAGE_ORDER, SortDirection.ASCENDING).setCurrentPageNum(1). setPageSize(1).
setPageSize(1). setPageCount(1);
setPageCount(1);
final JSONObject result = get(query);
final JSONObject result = get(query); final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONArray array = result.optJSONArray(Keys.RESULTS);
if (1 != array.length()) {
if (1 != array.length()) { return null;
return null; }
}
return array.optJSONObject(0);
return array.optJSONObject(0); }
}
@Override
@Override public JSONObject getByOrder(final int order) throws RepositoryException {
public JSONObject getByOrder(final int order) throws RepositoryException { final Query query = new Query().setFilter(
final Query query = new Query().addFilter(Page.PAGE_ORDER, FilterOperator.EQUAL, order). new PropertyFilter(Page.PAGE_ORDER, FilterOperator.EQUAL, order)).
setPageCount(1); setPageCount(1);
final JSONObject result = get(query); final JSONObject result = get(query);
final JSONArray array = result.optJSONArray(Keys.RESULTS); final JSONArray array = result.optJSONArray(Keys.RESULTS);
if (0 == array.length()) { if (0 == array.length()) {
return null; return null;
} }
return array.optJSONObject(0); return array.optJSONObject(0);
} }
@Override @Override
public List<JSONObject> getPages() throws RepositoryException { public List<JSONObject> getPages() throws RepositoryException {
final Query query = new Query().addSort( final Query query = new Query().addSort(
Page.PAGE_ORDER, SortDirection.ASCENDING).setPageCount(1); Page.PAGE_ORDER, SortDirection.ASCENDING).setPageCount(1);
final JSONObject result = get(query); final JSONObject result = get(query);
return CollectionUtils.jsonArrayToList(result.optJSONArray(Keys.RESULTS)); return CollectionUtils.jsonArrayToList(result.optJSONArray(Keys.RESULTS));
} }
/** /**
* Gets the {@link PageRepositoryImpl} singleton. * Gets the {@link PageRepositoryImpl} singleton.
* *
* @return the singleton * @return the singleton
*/ */
public static PageRepositoryImpl getInstance() { public static PageRepositoryImpl getInstance() {
return SINGLETON; return SINGLETON;
} }
/** /**
* Private constructor. * Private constructor.
* *
* @param name the specified name * @param name the specified name
*/ */
private PageRepositoryImpl(final String name) { private PageRepositoryImpl(final String name) {
super(name); super(name);
} }
} }
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.repository.impl; package org.b3log.solo.repository.impl;
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.b3log.solo.model.Article; import org.b3log.solo.model.Article;
import org.b3log.solo.model.Tag; import org.b3log.solo.model.Tag;
import org.b3log.solo.repository.TagArticleRepository; import org.b3log.solo.repository.TagArticleRepository;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.repository.AbstractRepository; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.FilterOperator; import org.b3log.latke.util.CollectionUtils;
import org.b3log.latke.repository.Query; import org.json.JSONArray;
import org.b3log.latke.repository.RepositoryException; import org.json.JSONObject;
import org.b3log.latke.repository.SortDirection;
import org.b3log.latke.util.CollectionUtils; /**
import org.json.JSONArray; * Tag-Article relation repository.
import org.json.JSONObject; *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
/** * @version 1.0.0.9, Nov 9, 2011
* Tag-Article relation repository. * @since 0.3.1
* */
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> public final class TagArticleRepositoryImpl extends AbstractRepository implements TagArticleRepository {
* @version 1.0.0.9, Nov 9, 2011
* @since 0.3.1 /**
*/ * Logger.
public final class TagArticleRepositoryImpl extends AbstractRepository implements TagArticleRepository { */
private static final Logger LOGGER = Logger.getLogger(TagArticleRepositoryImpl.class.getName());
/** /**
* Logger. * Singleton.
*/ */
private static final Logger LOGGER = Logger.getLogger(TagArticleRepositoryImpl.class.getName()); private static final TagArticleRepositoryImpl SINGLETON = new TagArticleRepositoryImpl(Tag.TAG + "_" + Article.ARTICLE);
/**
* Singleton. @Override
*/ public List<JSONObject> getByArticleId(final String articleId) throws RepositoryException {
private static final TagArticleRepositoryImpl SINGLETON = new TagArticleRepositoryImpl(Tag.TAG + "_" + Article.ARTICLE); final Query query = new Query().setFilter(
new PropertyFilter(Article.ARTICLE + "_" + Keys.OBJECT_ID, FilterOperator.EQUAL, articleId)).
@Override setPageCount(1);
public List<JSONObject> getByArticleId(final String articleId) throws RepositoryException {
final Query query = new Query().addFilter(Article.ARTICLE + "_" + Keys.OBJECT_ID, FilterOperator.EQUAL, articleId). final JSONObject result = get(query);
setPageCount(1); final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query); return CollectionUtils.jsonArrayToList(array);
final JSONArray array = result.optJSONArray(Keys.RESULTS); }
return CollectionUtils.jsonArrayToList(array); @Override
} public JSONObject getByTagId(final String tagId, final int currentPageNum, final int pageSize)
throws RepositoryException {
@Override final Query query = new Query().setFilter(
public JSONObject getByTagId(final String tagId, final int currentPageNum, final int pageSize) new PropertyFilter(Tag.TAG + "_" + Keys.OBJECT_ID, FilterOperator.EQUAL, tagId)).
throws RepositoryException { addSort(Article.ARTICLE + "_" + Keys.OBJECT_ID, SortDirection.DESCENDING).
final Query query = new Query().addFilter(Tag.TAG + "_" + Keys.OBJECT_ID, FilterOperator.EQUAL, tagId). setCurrentPageNum(currentPageNum).
addSort(Article.ARTICLE + "_" + Keys.OBJECT_ID, SortDirection.DESCENDING). setPageSize(pageSize).
setCurrentPageNum(currentPageNum). setPageCount(1);
setPageSize(pageSize).
setPageCount(1); return get(query);
}
return get(query);
} /**
* Gets the {@link TagArticleRepositoryImpl} singleton.
/** *
* Gets the {@link TagArticleRepositoryImpl} singleton. * @return the singleton
* */
* @return the singleton public static TagArticleRepositoryImpl getInstance() {
*/ return SINGLETON;
public static TagArticleRepositoryImpl getInstance() { }
return SINGLETON;
} /**
* Private constructor.
/** *
* Private constructor. * @param name the specified name
* */
* @param name the specified name private TagArticleRepositoryImpl(final String name) {
*/ super(name);
private TagArticleRepositoryImpl(final String name) { }
super(name); }
}
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.repository.impl; package org.b3log.solo.repository.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.b3log.solo.model.Tag; import org.b3log.solo.model.Tag;
import org.b3log.solo.repository.TagRepository; import org.b3log.solo.repository.TagRepository;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.repository.AbstractRepository; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.FilterOperator; import org.b3log.latke.util.CollectionUtils;
import org.b3log.latke.repository.Query; import org.json.JSONArray;
import org.b3log.latke.repository.RepositoryException; import org.json.JSONObject;
import org.b3log.latke.repository.SortDirection;
import org.b3log.latke.util.CollectionUtils; /**
import org.json.JSONArray; * Tag repository.
import org.json.JSONObject; *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
/** * @version 1.0.1.1, Nov 29, 2011
* Tag repository. * @since 0.3.1
* */
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> public final class TagRepositoryImpl extends AbstractRepository implements TagRepository {
* @version 1.0.1.1, Nov 29, 2011
* @since 0.3.1 /**
*/ * Logger.
public final class TagRepositoryImpl extends AbstractRepository implements TagRepository { */
private static final Logger LOGGER = Logger.getLogger(TagRepositoryImpl.class.getName());
/** /**
* Logger. * Singleton.
*/ */
private static final Logger LOGGER = Logger.getLogger(TagRepositoryImpl.class.getName()); private static final TagRepositoryImpl SINGLETON = new TagRepositoryImpl(Tag.TAG);
/** /**
* Singleton. * Tag-Article relation repository.
*/ */
private static final TagRepositoryImpl SINGLETON = new TagRepositoryImpl(Tag.TAG); private TagArticleRepositoryImpl tagArticleRepository = TagArticleRepositoryImpl.getInstance();
/**
* Tag-Article relation repository. @Override
*/ public JSONObject getByTitle(final String tagTitle) throws RepositoryException {
private TagArticleRepositoryImpl tagArticleRepository = TagArticleRepositoryImpl.getInstance(); final Query query = new Query().setFilter(
new PropertyFilter(Tag.TAG_TITLE, FilterOperator.EQUAL, tagTitle)).
@Override setPageCount(1);
public JSONObject getByTitle(final String tagTitle) throws RepositoryException {
final Query query = new Query().addFilter(Tag.TAG_TITLE, FilterOperator.EQUAL, tagTitle). final JSONObject result = get(query);
setPageCount(1); final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query); if (0 == array.length()) {
final JSONArray array = result.optJSONArray(Keys.RESULTS); return null;
}
if (0 == array.length()) {
return null; return array.optJSONObject(0);
} }
return array.optJSONObject(0); @Override
} public List<JSONObject> getMostUsedTags(final int num) throws RepositoryException {
final Query query = new Query().addSort(Tag.TAG_PUBLISHED_REFERENCE_COUNT, SortDirection.DESCENDING).
@Override setCurrentPageNum(1).
public List<JSONObject> getMostUsedTags(final int num) throws RepositoryException { setPageSize(num).
final Query query = new Query().addSort(Tag.TAG_PUBLISHED_REFERENCE_COUNT, SortDirection.DESCENDING). setPageCount(1);
setCurrentPageNum(1).
setPageSize(num). final JSONObject result = get(query);
setPageCount(1); final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query); return CollectionUtils.jsonArrayToList(array);
final JSONArray array = result.optJSONArray(Keys.RESULTS); }
return CollectionUtils.jsonArrayToList(array); @Override
} public List<JSONObject> getByArticleId(final String articleId) throws RepositoryException {
final List<JSONObject> ret = new ArrayList<JSONObject>();
@Override
public List<JSONObject> getByArticleId(final String articleId) throws RepositoryException { final List<JSONObject> tagArticleRelations = tagArticleRepository.getByArticleId(articleId);
final List<JSONObject> ret = new ArrayList<JSONObject>(); for (final JSONObject tagArticleRelation : tagArticleRelations) {
final String tagId = tagArticleRelation.optString(Tag.TAG + "_" + Keys.OBJECT_ID);
final List<JSONObject> tagArticleRelations = tagArticleRepository.getByArticleId(articleId); final JSONObject tag = get(tagId);
for (final JSONObject tagArticleRelation : tagArticleRelations) {
final String tagId = tagArticleRelation.optString(Tag.TAG + "_" + Keys.OBJECT_ID); ret.add(tag);
final JSONObject tag = get(tagId); }
ret.add(tag); return ret;
} }
return ret; /**
} * Gets the {@link TagRepositoryImpl} singleton.
*
/** * @return the singleton
* Gets the {@link TagRepositoryImpl} singleton. */
* public static TagRepositoryImpl getInstance() {
* @return the singleton return SINGLETON;
*/ }
public static TagRepositoryImpl getInstance() {
return SINGLETON; /**
} * Private constructor.
*
/** * @param name the specified name
* Private constructor. */
* private TagRepositoryImpl(final String name) {
* @param name the specified name super(name);
*/ }
private TagRepositoryImpl(final String name) { }
super(name);
}
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.repository.impl; package org.b3log.solo.repository.impl;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.model.Role; import org.b3log.latke.model.Role;
import org.b3log.latke.model.User; import org.b3log.latke.model.User;
import org.b3log.latke.repository.AbstractRepository; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.FilterOperator; import org.b3log.solo.repository.UserRepository;
import org.b3log.latke.repository.Query; import org.json.JSONArray;
import org.b3log.latke.repository.RepositoryException; import org.json.JSONObject;
import org.b3log.solo.repository.UserRepository;
import org.json.JSONArray; /**
import org.json.JSONObject; * User repository.
*
/** * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* User repository. * @version 1.0.0.8, Nov 10, 2011
* * @since 0.3.1
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> */
* @version 1.0.0.8, Nov 10, 2011 public final class UserRepositoryImpl extends AbstractRepository implements UserRepository {
* @since 0.3.1
*/ /**
public final class UserRepositoryImpl extends AbstractRepository implements UserRepository { * Logger.
*/
/** private static final Logger LOGGER = Logger.getLogger(UserRepositoryImpl.class.getName());
* Logger. /**
*/ * Singleton.
private static final Logger LOGGER = Logger.getLogger(UserRepositoryImpl.class.getName()); */
/** private static final UserRepositoryImpl SINGLETON = new UserRepositoryImpl(User.USER);
* Singleton.
*/ @Override
private static final UserRepositoryImpl SINGLETON = new UserRepositoryImpl(User.USER); public JSONObject getByEmail(final String email) throws RepositoryException {
final Query query = new Query().setPageCount(1);
@Override query.setFilter(
public JSONObject getByEmail(final String email) throws RepositoryException { new PropertyFilter(User.USER_EMAIL, FilterOperator.EQUAL, email.toLowerCase().trim()));
final Query query = new Query().setPageCount(1);
query.addFilter(User.USER_EMAIL, FilterOperator.EQUAL, email.toLowerCase().trim()); final JSONObject result = get(query);
final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONObject result = get(query);
final JSONArray array = result.optJSONArray(Keys.RESULTS); if (0 == array.length()) {
return null;
if (0 == array.length()) { }
return null;
} return array.optJSONObject(0);
}
return array.optJSONObject(0);
} @Override
public JSONObject getAdmin() throws RepositoryException {
@Override final Query query = new Query().setFilter(
public JSONObject getAdmin() throws RepositoryException { new PropertyFilter(User.USER_ROLE, FilterOperator.EQUAL, Role.ADMIN_ROLE)).setPageCount(1);
final Query query = new Query().addFilter(User.USER_ROLE, FilterOperator.EQUAL, Role.ADMIN_ROLE).setPageCount(1); final JSONObject result = get(query);
final JSONObject result = get(query); final JSONArray array = result.optJSONArray(Keys.RESULTS);
final JSONArray array = result.optJSONArray(Keys.RESULTS);
if (0 == array.length()) {
if (0 == array.length()) { return null;
return null; }
}
return array.optJSONObject(0);
return array.optJSONObject(0); }
}
@Override
@Override public boolean isAdminEmail(final String email) throws RepositoryException {
public boolean isAdminEmail(final String email) throws RepositoryException { final JSONObject user = getByEmail(email);
final JSONObject user = getByEmail(email);
if (null == user) {
if (null == user) { return false;
return false; }
}
return Role.ADMIN_ROLE.equals(user.optString(User.USER_ROLE));
return Role.ADMIN_ROLE.equals(user.optString(User.USER_ROLE)); }
}
/**
/** * Gets the {@link UserRepositoryImpl} singleton.
* Gets the {@link UserRepositoryImpl} singleton. *
* * @return the singleton
* @return the singleton */
*/ public static UserRepositoryImpl getInstance() {
public static UserRepositoryImpl getInstance() { return SINGLETON;
return SINGLETON; }
}
/**
/** * Private constructor.
* Private constructor. *
* * @param name the specified name
* @param name the specified name */
*/ private UserRepositoryImpl(final String name) {
private UserRepositoryImpl(final String name) { super(name);
super(name); }
} }
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.service; package org.b3log.solo.service;
import org.b3log.solo.repository.ArchiveDateArticleRepository; import org.b3log.solo.repository.ArchiveDateArticleRepository;
import org.b3log.solo.repository.impl.ArchiveDateArticleRepositoryImpl; import org.b3log.solo.repository.impl.ArchiveDateArticleRepositoryImpl;
import java.util.Set; import java.util.Set;
import org.b3log.solo.model.Sign; import org.b3log.solo.model.Sign;
import org.b3log.solo.model.Tag; import org.b3log.solo.model.Tag;
import java.util.Date; import java.util.Date;
import org.b3log.latke.model.User; import org.b3log.latke.model.User;
import org.b3log.solo.model.Common; import org.b3log.solo.model.Common;
import org.b3log.solo.util.Articles; import org.b3log.solo.util.Articles;
import org.b3log.latke.repository.FilterOperator; import org.b3log.latke.repository.FilterOperator;
import org.b3log.latke.repository.SortDirection; import org.b3log.latke.repository.SortDirection;
import org.b3log.latke.repository.Query; import org.b3log.latke.repository.Query;
import org.b3log.latke.model.Pagination; import org.b3log.latke.model.Pagination;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.repository.RepositoryException; import org.b3log.latke.repository.*;
import org.b3log.latke.service.ServiceException; import org.b3log.latke.service.ServiceException;
import org.b3log.latke.util.CollectionUtils; import org.b3log.latke.util.CollectionUtils;
import org.b3log.latke.util.Paginator; import org.b3log.latke.util.Paginator;
import org.b3log.latke.util.Stopwatchs; import org.b3log.latke.util.Stopwatchs;
import org.b3log.latke.util.Strings; import org.b3log.latke.util.Strings;
import org.b3log.solo.model.Article; import org.b3log.solo.model.Article;
import org.b3log.solo.model.Preference; import org.b3log.solo.model.Preference;
import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.TagArticleRepository; import org.b3log.solo.repository.TagArticleRepository;
import org.b3log.solo.repository.TagRepository; import org.b3log.solo.repository.TagRepository;
import org.b3log.solo.repository.impl.ArticleRepositoryImpl; import org.b3log.solo.repository.impl.ArticleRepositoryImpl;
import org.b3log.solo.repository.impl.TagArticleRepositoryImpl; import org.b3log.solo.repository.impl.TagArticleRepositoryImpl;
import org.b3log.solo.repository.impl.TagRepositoryImpl; import org.b3log.solo.repository.impl.TagRepositoryImpl;
import org.b3log.solo.util.Statistics; import org.b3log.solo.util.Statistics;
import org.b3log.solo.util.comparator.Comparators; import org.b3log.solo.util.comparator.Comparators;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
import static org.b3log.solo.model.Article.*; import static org.b3log.solo.model.Article.*;
import org.b3log.solo.util.Markdowns; import org.b3log.solo.util.Markdowns;
/** /**
* Article query service. * Article query service.
* *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.1.0, May 10, 2012 * @version 1.0.1.0, May 10, 2012
* @since 0.3.5 * @since 0.3.5
*/ */
public final class ArticleQueryService { public final class ArticleQueryService {
/** /**
* Logger. * Logger.
*/ */
private static final Logger LOGGER = Logger.getLogger(ArticleQueryService.class.getName()); private static final Logger LOGGER = Logger.getLogger(ArticleQueryService.class.getName());
/** /**
* Article repository. * Article repository.
*/ */
private ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance(); private ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance();
/** /**
* Preference query service. * Preference query service.
*/ */
private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance(); private PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance();
/** /**
* Tag repository. * Tag repository.
*/ */
private TagRepository tagRepository = TagRepositoryImpl.getInstance(); private TagRepository tagRepository = TagRepositoryImpl.getInstance();
/** /**
* Tag-Article repository. * Tag-Article repository.
*/ */
private TagArticleRepository tagArticleRepository = TagArticleRepositoryImpl.getInstance(); private TagArticleRepository tagArticleRepository = TagArticleRepositoryImpl.getInstance();
/** /**
* Archive date-Article repository. * Archive date-Article repository.
*/ */
private ArchiveDateArticleRepository archiveDateArticleRepository = ArchiveDateArticleRepositoryImpl.getInstance(); private ArchiveDateArticleRepository archiveDateArticleRepository = ArchiveDateArticleRepositoryImpl.getInstance();
/** /**
* Statistic utilities. * Statistic utilities.
*/ */
private Statistics statistics = Statistics.getInstance(); private Statistics statistics = Statistics.getInstance();
/** /**
* Article utilities. * Article utilities.
*/ */
private static Articles articleUtils = Articles.getInstance(); private static Articles articleUtils = Articles.getInstance();
/** /**
* Gets the recent articles with the specified fetch size. * Gets the recent articles with the specified fetch size.
* *
* @param fetchSize the specified fetch size * @param fetchSize the specified fetch size
* @return a list of json object, its size less or equal to the specified * @return a list of json object, its size less or equal to the specified
* fetch size * fetch size
* @throws ServiceException service exception * @throws ServiceException service exception
*/ */
public List<JSONObject> getRecentArticles(final int fetchSize) throws ServiceException { public List<JSONObject> getRecentArticles(final int fetchSize) throws ServiceException {
try { try {
return articleRepository.getRecentArticles(fetchSize); return articleRepository.getRecentArticles(fetchSize);
} catch (final RepositoryException e) { } catch (final RepositoryException e) {
LOGGER.log(Level.SEVERE, "Gets recent articles failed", e); LOGGER.log(Level.SEVERE, "Gets recent articles failed", e);
return Collections.emptyList(); return Collections.emptyList();
} }
} }
/** /**
* Gets an article by the specified article id. * Gets an article by the specified article id.
* *
* <p> * <p>
* <b>Note</b>: The article content and abstract is raw (no editor type processing). * <b>Note</b>: The article content and abstract is raw (no editor type processing).
* </p> * </p>
* *
* @param articleId the specified article id * @param articleId the specified article id
* @return for example, * @return for example,
* <pre> * <pre>
* { * {
* "article": { * "article": {
* "oId": "", * "oId": "",
* "articleTitle": "", * "articleTitle": "",
* "articleAbstract": "", * "articleAbstract": "",
* "articleContent": "", * "articleContent": "",
* "articlePermalink": "", * "articlePermalink": "",
* "articleHadBeenPublished": boolean, * "articleHadBeenPublished": boolean,
* "articleCreateDate": java.util.Date, * "articleCreateDate": java.util.Date,
* "articleTags": [{ * "articleTags": [{
* "oId": "", * "oId": "",
* "tagTitle": "" * "tagTitle": ""
* }, ....], * }, ....],
* "articleSignId": "", * "articleSignId": "",
* "articleViewPwd": "", * "articleViewPwd": "",
* "articleEditorType": "", * "articleEditorType": "",
* "signs": [{ * "signs": [{
* "oId": "", * "oId": "",
* "signHTML": "" * "signHTML": ""
* }, ....] * }, ....]
* } * }
* } * }
* </pre>, returns {@code null} if not found * </pre>, returns {@code null} if not found
* @throws ServiceException service exception * @throws ServiceException service exception
*/ */
public JSONObject getArticle(final String articleId) throws ServiceException { public JSONObject getArticle(final String articleId) throws ServiceException {
try { try {
final JSONObject ret = new JSONObject(); final JSONObject ret = new JSONObject();
final JSONObject article = articleRepository.get(articleId); final JSONObject article = articleRepository.get(articleId);
if (null == article) { if (null == article) {
return null; return null;
} }
ret.put(ARTICLE, article); ret.put(ARTICLE, article);
// Tags // Tags
final JSONArray tags = new JSONArray(); final JSONArray tags = new JSONArray();
final List<JSONObject> tagArticleRelations = tagArticleRepository.getByArticleId(articleId); final List<JSONObject> tagArticleRelations = tagArticleRepository.getByArticleId(articleId);
for (int i = 0; i < tagArticleRelations.size(); i++) { for (int i = 0; i < tagArticleRelations.size(); i++) {
final JSONObject tagArticleRelation = tagArticleRelations.get(i); final JSONObject tagArticleRelation = tagArticleRelations.get(i);
final String tagId = tagArticleRelation.getString(Tag.TAG + "_" + Keys.OBJECT_ID); final String tagId = tagArticleRelation.getString(Tag.TAG + "_" + Keys.OBJECT_ID);
final JSONObject tag = tagRepository.get(tagId); final JSONObject tag = tagRepository.get(tagId);
tags.put(tag); tags.put(tag);
} }
article.put(ARTICLE_TAGS_REF, tags); article.put(ARTICLE_TAGS_REF, tags);
// Signs // Signs
final JSONObject preference = preferenceQueryService.getPreference(); final JSONObject preference = preferenceQueryService.getPreference();
article.put(Sign.SIGNS, new JSONArray(preference.getString(Preference.SIGNS))); article.put(Sign.SIGNS, new JSONArray(preference.getString(Preference.SIGNS)));
// Remove unused properties // Remove unused properties
article.remove(ARTICLE_AUTHOR_EMAIL); article.remove(ARTICLE_AUTHOR_EMAIL);
article.remove(ARTICLE_COMMENT_COUNT); article.remove(ARTICLE_COMMENT_COUNT);
article.remove(ARTICLE_IS_PUBLISHED); article.remove(ARTICLE_IS_PUBLISHED);
article.remove(ARTICLE_PUT_TOP); article.remove(ARTICLE_PUT_TOP);
article.remove(ARTICLE_UPDATE_DATE); article.remove(ARTICLE_UPDATE_DATE);
article.remove(ARTICLE_VIEW_COUNT); article.remove(ARTICLE_VIEW_COUNT);
article.remove(ARTICLE_RANDOM_DOUBLE); article.remove(ARTICLE_RANDOM_DOUBLE);
LOGGER.log(Level.FINER, "Got an article[id={0}]", articleId); LOGGER.log(Level.FINER, "Got an article[id={0}]", articleId);
return ret; return ret;
} catch (final Exception e) { } catch (final Exception e) {
LOGGER.log(Level.SEVERE, "Gets an article failed", e); LOGGER.log(Level.SEVERE, "Gets an article failed", e);
throw new ServiceException(e); throw new ServiceException(e);
} }
} }
/** /**
* Gets articles(by crate date descending) by the specified request json * Gets articles(by crate date descending) by the specified request json
* object. * object.
* *
* <p> * <p>
* If the property "articleIsPublished" of the specified request json object is {@code true}, the returned articles all are published, * If the property "articleIsPublished" of the specified request json object is {@code true}, the returned articles all are published,
* {@code false} otherwise. * {@code false} otherwise.
* </p> * </p>
* *
* <p> * <p>
* Specified the "excludes" for results properties exclusion. * Specified the "excludes" for results properties exclusion.
* </p> * </p>
* *
* @param requestJSONObject the specified request json object, for example, * @param requestJSONObject the specified request json object, for example,
* <pre> * <pre>
* { * {
* "paginationCurrentPageNum": 1, * "paginationCurrentPageNum": 1,
* "paginationPageSize": 20, * "paginationPageSize": 20,
* "paginationWindowSize": 10, * "paginationWindowSize": 10,
* "articleIsPublished": boolean, * "articleIsPublished": boolean,
* "excludes": ["", ....] // Optional * "excludes": ["", ....] // Optional
* }, see {@link Pagination} for more details * }, see {@link Pagination} for more details
* </pre> * </pre>
* @return for example, * @return for example,
* <pre> * <pre>
* { * {
* "pagination": { * "pagination": {
* "paginationPageCount": 100, * "paginationPageCount": 100,
* "paginationPageNums": [1, 2, 3, 4, 5] * "paginationPageNums": [1, 2, 3, 4, 5]
* }, * },
* "articles": [{ * "articles": [{
* "oId": "", * "oId": "",
* "articleTitle": "", * "articleTitle": "",
* "articleCommentCount": int, * "articleCommentCount": int,
* "articleCreateTime"; long, * "articleCreateTime"; long,
* "articleViewCount": int, * "articleViewCount": int,
* "articleTags": "tag1, tag2, ....", * "articleTags": "tag1, tag2, ....",
* "articlePutTop": boolean, * "articlePutTop": boolean,
* "articleSignId": "", * "articleSignId": "",
* "articleViewPwd": "", * "articleViewPwd": "",
* "articleEditorType": "", * "articleEditorType": "",
* .... // Specified by the "excludes" * .... // Specified by the "excludes"
* }, ....] * }, ....]
* } * }
* </pre>, order by article update date and sticky(put top). * </pre>, order by article update date and sticky(put top).
* @throws ServiceException service exception * @throws ServiceException service exception
* @see Pagination * @see Pagination
*/ */
public JSONObject getArticles(final JSONObject requestJSONObject) throws ServiceException { public JSONObject getArticles(final JSONObject requestJSONObject) throws ServiceException {
final JSONObject ret = new JSONObject(); final JSONObject ret = new JSONObject();
try { try {
final int currentPageNum = requestJSONObject.getInt(Pagination.PAGINATION_CURRENT_PAGE_NUM); final int currentPageNum = requestJSONObject.getInt(Pagination.PAGINATION_CURRENT_PAGE_NUM);
final int pageSize = requestJSONObject.getInt(Pagination.PAGINATION_PAGE_SIZE); final int pageSize = requestJSONObject.getInt(Pagination.PAGINATION_PAGE_SIZE);
final int windowSize = requestJSONObject.getInt(Pagination.PAGINATION_WINDOW_SIZE); final int windowSize = requestJSONObject.getInt(Pagination.PAGINATION_WINDOW_SIZE);
final boolean articleIsPublished = requestJSONObject.optBoolean(ARTICLE_IS_PUBLISHED, true); final boolean articleIsPublished = requestJSONObject.optBoolean(ARTICLE_IS_PUBLISHED, true);
final Query query = new Query().setCurrentPageNum(currentPageNum). final Query query = new Query().setCurrentPageNum(currentPageNum).
setPageSize(pageSize). setPageSize(pageSize).
addSort(ARTICLE_PUT_TOP, SortDirection.DESCENDING). addSort(ARTICLE_PUT_TOP, SortDirection.DESCENDING).
addSort(ARTICLE_CREATE_DATE, SortDirection.DESCENDING). addSort(ARTICLE_CREATE_DATE, SortDirection.DESCENDING).
addFilter(ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, articleIsPublished); setFilter(
new PropertyFilter(ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, articleIsPublished));
int articleCount = statistics.getBlogArticleCount();
if (!articleIsPublished) { int articleCount = statistics.getBlogArticleCount();
articleCount -= statistics.getPublishedBlogArticleCount(); if (!articleIsPublished) {
} articleCount -= statistics.getPublishedBlogArticleCount();
}
final int pageCount = (int) Math.ceil((double) articleCount / (double) pageSize);
query.setPageCount(pageCount); final int pageCount = (int) Math.ceil((double) articleCount / (double) pageSize);
query.setPageCount(pageCount);
final JSONObject result = articleRepository.get(query);
final JSONObject result = articleRepository.get(query);
final JSONObject pagination = new JSONObject();
ret.put(Pagination.PAGINATION, pagination); final JSONObject pagination = new JSONObject();
final List<Integer> pageNums = Paginator.paginate(currentPageNum, pageSize, pageCount, windowSize); ret.put(Pagination.PAGINATION, pagination);
pagination.put(Pagination.PAGINATION_PAGE_COUNT, pageCount); final List<Integer> pageNums = Paginator.paginate(currentPageNum, pageSize, pageCount, windowSize);
pagination.put(Pagination.PAGINATION_PAGE_NUMS, pageNums); pagination.put(Pagination.PAGINATION_PAGE_COUNT, pageCount);
pagination.put(Pagination.PAGINATION_PAGE_NUMS, pageNums);
final JSONArray articles = result.getJSONArray(Keys.RESULTS);
JSONArray excludes = requestJSONObject.optJSONArray(Keys.EXCLUDES); final JSONArray articles = result.getJSONArray(Keys.RESULTS);
excludes = null == excludes ? new JSONArray() : excludes; JSONArray excludes = requestJSONObject.optJSONArray(Keys.EXCLUDES);
excludes = null == excludes ? new JSONArray() : excludes;
for (int i = 0; i < articles.length(); i++) {
final JSONObject article = articles.getJSONObject(i); for (int i = 0; i < articles.length(); i++) {
final JSONObject author = articleUtils.getAuthor(article); final JSONObject article = articles.getJSONObject(i);
final String authorName = author.getString(User.USER_NAME); final JSONObject author = articleUtils.getAuthor(article);
article.put(Common.AUTHOR_NAME, authorName); final String authorName = author.getString(User.USER_NAME);
article.put(Common.AUTHOR_NAME, authorName);
article.put(ARTICLE_CREATE_TIME, ((Date) article.get(ARTICLE_CREATE_DATE)).getTime());
article.put(ARTICLE_CREATE_TIME, ((Date) article.get(ARTICLE_CREATE_DATE)).getTime());
// Markdown to HTML for content and abstract
markdown(article); // Markdown to HTML for content and abstract
markdown(article);
// Remove unused properties
for (int j = 0; j < excludes.length(); j++) { // Remove unused properties
article.remove(excludes.optString(j)); for (int j = 0; j < excludes.length(); j++) {
} article.remove(excludes.optString(j));
} }
}
ret.put(ARTICLES, articles);
ret.put(ARTICLES, articles);
return ret;
} catch (final Exception e) { return ret;
LOGGER.log(Level.SEVERE, "Gets articles failed", e); } catch (final Exception e) {
LOGGER.log(Level.SEVERE, "Gets articles failed", e);
throw new ServiceException(e);
} throw new ServiceException(e);
} }
}
/**
* Gets a list of published articles with the specified tag id, current page number and page size. /**
* * Gets a list of published articles with the specified tag id, current page number and page size.
* @param tagId the specified tag id *
* @param currentPageNum the specified current page number * @param tagId the specified tag id
* @param pageSize the specified page size * @param currentPageNum the specified current page number
* @return a list of articles, returns an empty list if not found * @param pageSize the specified page size
* @throws ServiceException service exception * @return a list of articles, returns an empty list if not found
*/ * @throws ServiceException service exception
public List<JSONObject> getArticlesByTag(final String tagId, final int currentPageNum, final int pageSize) */
throws ServiceException { public List<JSONObject> getArticlesByTag(final String tagId, final int currentPageNum, final int pageSize)
try { throws ServiceException {
JSONObject result = tagArticleRepository.getByTagId(tagId, currentPageNum, pageSize); try {
final JSONArray tagArticleRelations = result.getJSONArray(Keys.RESULTS); JSONObject result = tagArticleRepository.getByTagId(tagId, currentPageNum, pageSize);
if (0 == tagArticleRelations.length()) { final JSONArray tagArticleRelations = result.getJSONArray(Keys.RESULTS);
return Collections.emptyList(); if (0 == tagArticleRelations.length()) {
} return Collections.emptyList();
}
final Set<String> articleIds = new HashSet<String>();
for (int i = 0; i < tagArticleRelations.length(); i++) { final Set<String> articleIds = new HashSet<String>();
final JSONObject tagArticleRelation = tagArticleRelations.getJSONObject(i); for (int i = 0; i < tagArticleRelations.length(); i++) {
final String articleId = tagArticleRelation.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID); final JSONObject tagArticleRelation = tagArticleRelations.getJSONObject(i);
final String articleId = tagArticleRelation.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID);
articleIds.add(articleId);
} articleIds.add(articleId);
}
final List<JSONObject> ret = new ArrayList<JSONObject>();
final List<JSONObject> ret = new ArrayList<JSONObject>();
final Query query = new Query().addFilter(Keys.OBJECT_ID, FilterOperator.IN, articleIds).
setPageCount(1).index(Article.ARTICLE_PERMALINK); final Query query = new Query().setFilter(
result = articleRepository.get(query); new PropertyFilter(Keys.OBJECT_ID, FilterOperator.IN, articleIds)).
final JSONArray articles = result.getJSONArray(Keys.RESULTS); setPageCount(1).index(Article.ARTICLE_PERMALINK);
for (int i = 0; i < articles.length(); i++) { result = articleRepository.get(query);
final JSONObject article = articles.getJSONObject(i); final JSONArray articles = result.getJSONArray(Keys.RESULTS);
for (int i = 0; i < articles.length(); i++) {
if (!article.getBoolean(Article.ARTICLE_IS_PUBLISHED)) { final JSONObject article = articles.getJSONObject(i);
// Skips the unpublished article
continue; if (!article.getBoolean(Article.ARTICLE_IS_PUBLISHED)) {
} // Skips the unpublished article
continue;
// Markdown to HTML for content and abstract }
markdown(article);
// Markdown to HTML for content and abstract
ret.add(article); markdown(article);
}
ret.add(article);
return ret; }
} catch (final Exception e) {
LOGGER.log(Level.SEVERE, "Gets articles by tag[id=" + tagId + "] failed", e); return ret;
throw new ServiceException(e); } catch (final Exception e) {
} LOGGER.log(Level.SEVERE, "Gets articles by tag[id=" + tagId + "] failed", e);
} throw new ServiceException(e);
}
/** }
* Gets a list of published articles with the specified archive date id, current page number and page size.
* /**
* @param archiveDateId the specified archive date id * Gets a list of published articles with the specified archive date id, current page number and page size.
* @param currentPageNum the specified current page number *
* @param pageSize the specified page size * @param archiveDateId the specified archive date id
* @return a list of articles, returns an empty list if not found * @param currentPageNum the specified current page number
* @throws ServiceException service exception * @param pageSize the specified page size
*/ * @return a list of articles, returns an empty list if not found
public List<JSONObject> getArticlesByArchiveDate(final String archiveDateId, final int currentPageNum, final int pageSize) * @throws ServiceException service exception
throws ServiceException { */
try { public List<JSONObject> getArticlesByArchiveDate(final String archiveDateId, final int currentPageNum, final int pageSize)
JSONObject result = archiveDateArticleRepository.getByArchiveDateId(archiveDateId, currentPageNum, pageSize); throws ServiceException {
try {
final JSONArray relations = result.getJSONArray(Keys.RESULTS); JSONObject result = archiveDateArticleRepository.getByArchiveDateId(archiveDateId, currentPageNum, pageSize);
if (0 == relations.length()) {
return Collections.emptyList(); final JSONArray relations = result.getJSONArray(Keys.RESULTS);
} if (0 == relations.length()) {
return Collections.emptyList();
final Set<String> articleIds = new HashSet<String>(); }
for (int i = 0; i < relations.length(); i++) {
final JSONObject relation = relations.getJSONObject(i); final Set<String> articleIds = new HashSet<String>();
final String articleId = relation.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID); for (int i = 0; i < relations.length(); i++) {
final JSONObject relation = relations.getJSONObject(i);
articleIds.add(articleId); final String articleId = relation.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID);
}
articleIds.add(articleId);
final List<JSONObject> ret = new ArrayList<JSONObject>(); }
final Query query = new Query().addFilter(Keys.OBJECT_ID, FilterOperator.IN, articleIds). final List<JSONObject> ret = new ArrayList<JSONObject>();
setPageCount(1).index(Article.ARTICLE_PERMALINK);
result = articleRepository.get(query); final Query query = new Query().setFilter(
final JSONArray articles = result.getJSONArray(Keys.RESULTS); new PropertyFilter(Keys.OBJECT_ID, FilterOperator.IN, articleIds)).
for (int i = 0; i < articles.length(); i++) { setPageCount(1).index(Article.ARTICLE_PERMALINK);
final JSONObject article = articles.getJSONObject(i); result = articleRepository.get(query);
final JSONArray articles = result.getJSONArray(Keys.RESULTS);
if (!article.getBoolean(Article.ARTICLE_IS_PUBLISHED)) { for (int i = 0; i < articles.length(); i++) {
// Skips the unpublished article final JSONObject article = articles.getJSONObject(i);
continue;
} if (!article.getBoolean(Article.ARTICLE_IS_PUBLISHED)) {
// Skips the unpublished article
// Markdown to HTML for content and abstract continue;
markdown(article); }
ret.add(article); // Markdown to HTML for content and abstract
} markdown(article);
return ret; ret.add(article);
} catch (final Exception e) { }
LOGGER.log(Level.SEVERE, "Gets articles by archive date[id=" + archiveDateId + "] failed", e);
throw new ServiceException(e); return ret;
} } catch (final Exception e) {
} LOGGER.log(Level.SEVERE, "Gets articles by archive date[id=" + archiveDateId + "] failed", e);
throw new ServiceException(e);
/** }
* Gets a list of articles randomly with the specified fetch size. }
*
* <p> /**
* <b>Note</b>: The article content and abstract is raw (no editor type processing). * Gets a list of articles randomly with the specified fetch size.
* </p> *
* * <p>
* @param fetchSize the specified fetch size * <b>Note</b>: The article content and abstract is raw (no editor type processing).
* @return a list of json objects, its size less or equal to the specified * </p>
* fetch size *
* @throws ServiceException service exception * @param fetchSize the specified fetch size
*/ * @return a list of json objects, its size less or equal to the specified
public List<JSONObject> getArticlesRandomly(final int fetchSize) throws ServiceException { * fetch size
try { * @throws ServiceException service exception
final List<JSONObject> ret = articleRepository.getRandomly(fetchSize); */
public List<JSONObject> getArticlesRandomly(final int fetchSize) throws ServiceException {
removeUnusedProperties(ret); try {
final List<JSONObject> ret = articleRepository.getRandomly(fetchSize);
return ret;
} catch (final RepositoryException e) { removeUnusedProperties(ret);
LOGGER.log(Level.SEVERE, "Gets articles randomly failed[fetchSize=" + fetchSize + "]", e);
throw new ServiceException(e); return ret;
} } catch (final RepositoryException e) {
} LOGGER.log(Level.SEVERE, "Gets articles randomly failed[fetchSize=" + fetchSize + "]", e);
throw new ServiceException(e);
/** }
* Gets the relevant published articles of the specified article. }
*
* <p> /**
* <b>Note</b>: The article content and abstract is raw (no editor type processing). * Gets the relevant published articles of the specified article.
* </p> *
* * <p>
* @param article the specified article * <b>Note</b>: The article content and abstract is raw (no editor type processing).
* @param preference the specified preference * </p>
* @return a list of articles, returns an empty list if not found *
* @throws ServiceException service exception * @param article the specified article
*/ * @param preference the specified preference
public List<JSONObject> getRelevantArticles(final JSONObject article, final JSONObject preference) * @return a list of articles, returns an empty list if not found
throws ServiceException { * @throws ServiceException service exception
try { */
final int displayCnt = preference.getInt(Preference.RELEVANT_ARTICLES_DISPLAY_CNT); public List<JSONObject> getRelevantArticles(final JSONObject article, final JSONObject preference)
final String[] tagTitles = article.getString(Article.ARTICLE_TAGS_REF).split(","); throws ServiceException {
final int maxTagCnt = displayCnt > tagTitles.length ? tagTitles.length : displayCnt; try {
final String articleId = article.getString(Keys.OBJECT_ID); final int displayCnt = preference.getInt(Preference.RELEVANT_ARTICLES_DISPLAY_CNT);
final String[] tagTitles = article.getString(Article.ARTICLE_TAGS_REF).split(",");
final List<JSONObject> articles = new ArrayList<JSONObject>(); final int maxTagCnt = displayCnt > tagTitles.length ? tagTitles.length : displayCnt;
for (int i = 0; i < maxTagCnt; i++) { // XXX: should average by tag? final String articleId = article.getString(Keys.OBJECT_ID);
final String tagTitle = tagTitles[i];
final JSONObject tag = tagRepository.getByTitle(tagTitle); final List<JSONObject> articles = new ArrayList<JSONObject>();
final String tagId = tag.getString(Keys.OBJECT_ID); for (int i = 0; i < maxTagCnt; i++) { // XXX: should average by tag?
final JSONObject result = tagArticleRepository.getByTagId(tagId, 1, displayCnt); final String tagTitle = tagTitles[i];
final JSONArray tagArticleRelations = result.getJSONArray(Keys.RESULTS); final JSONObject tag = tagRepository.getByTitle(tagTitle);
final String tagId = tag.getString(Keys.OBJECT_ID);
final int relationSize = displayCnt < tagArticleRelations.length() ? displayCnt : tagArticleRelations.length(); final JSONObject result = tagArticleRepository.getByTagId(tagId, 1, displayCnt);
for (int j = 0; j < relationSize; j++) { final JSONArray tagArticleRelations = result.getJSONArray(Keys.RESULTS);
final JSONObject tagArticleRelation = tagArticleRelations.getJSONObject(j);
final String relatedArticleId = tagArticleRelation.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID); final int relationSize = displayCnt < tagArticleRelations.length() ? displayCnt : tagArticleRelations.length();
if (articleId.equals(relatedArticleId)) { for (int j = 0; j < relationSize; j++) {
continue; final JSONObject tagArticleRelation = tagArticleRelations.getJSONObject(j);
} final String relatedArticleId = tagArticleRelation.getString(Article.ARTICLE + "_" + Keys.OBJECT_ID);
if (articleId.equals(relatedArticleId)) {
final JSONObject relevant = articleRepository.get(relatedArticleId); continue;
if (!relevant.getBoolean(Article.ARTICLE_IS_PUBLISHED)) { }
continue;
} final JSONObject relevant = articleRepository.get(relatedArticleId);
if (!relevant.getBoolean(Article.ARTICLE_IS_PUBLISHED)) {
boolean existed = false; continue;
for (final JSONObject relevantArticle : articles) { }
if (relevantArticle.getString(Keys.OBJECT_ID).
equals(relevant.getString(Keys.OBJECT_ID))) { boolean existed = false;
existed = true; for (final JSONObject relevantArticle : articles) {
} if (relevantArticle.getString(Keys.OBJECT_ID).
} equals(relevant.getString(Keys.OBJECT_ID))) {
existed = true;
if (!existed) { }
articles.add(relevant); }
}
} if (!existed) {
} articles.add(relevant);
}
Collections.sort(articles, Comparators.ARTICLE_UPDATE_DATE_COMPARATOR); }
removeUnusedProperties(articles); }
if (displayCnt > articles.size()) { Collections.sort(articles, Comparators.ARTICLE_UPDATE_DATE_COMPARATOR);
return articles; removeUnusedProperties(articles);
}
if (displayCnt > articles.size()) {
final List<Integer> randomIntegers = CollectionUtils.getRandomIntegers(0, articles.size() - 1, displayCnt); return articles;
final List<JSONObject> ret = new ArrayList<JSONObject>(); }
for (final int index : randomIntegers) {
ret.add(articles.get(index)); final List<Integer> randomIntegers = CollectionUtils.getRandomIntegers(0, articles.size() - 1, displayCnt);
} final List<JSONObject> ret = new ArrayList<JSONObject>();
for (final int index : randomIntegers) {
return ret; ret.add(articles.get(index));
} catch (final Exception e) { }
LOGGER.log(Level.SEVERE, "Gets relevant articles failed", e);
return ret;
throw new ServiceException(e); } catch (final Exception e) {
} LOGGER.log(Level.SEVERE, "Gets relevant articles failed", e);
}
throw new ServiceException(e);
/** }
* Determines an article specified by the given article id is published. }
*
* @param articleId the given article id /**
* @return {@code true} if it is published * Determines an article specified by the given article id is published.
* @throws ServiceException service exception *
*/ * @param articleId the given article id
public boolean isArticlePublished(final String articleId) throws ServiceException { * @return {@code true} if it is published
try { * @throws ServiceException service exception
return articleRepository.isPublished(articleId); */
} catch (final RepositoryException e) { public boolean isArticlePublished(final String articleId) throws ServiceException {
LOGGER.log(Level.SEVERE, "Determines the article publish status failed[articleId=" + articleId + "]", e); try {
throw new ServiceException(e); return articleRepository.isPublished(articleId);
} } catch (final RepositoryException e) {
} LOGGER.log(Level.SEVERE, "Determines the article publish status failed[articleId=" + articleId + "]", e);
throw new ServiceException(e);
/** }
* Gets the next article(by create date) by the specified article id. }
*
* <p> /**
* <b>Note</b>: The article content and abstract is raw (no editor type processing). * Gets the next article(by create date) by the specified article id.
* </p> *
* * <p>
* @param articleId the specified article id * <b>Note</b>: The article content and abstract is raw (no editor type processing).
* @return the previous article, * </p>
* <pre> *
* { * @param articleId the specified article id
* "articleTitle": "", * @return the previous article,
* "articlePermalink": "" * <pre>
* } * {
* </pre> * "articleTitle": "",
* returns {@code null} if not found * "articlePermalink": ""
* @throws ServiceException service exception * }
*/ * </pre>
public JSONObject getNextArticle(final String articleId) throws ServiceException { * returns {@code null} if not found
try { * @throws ServiceException service exception
return articleRepository.getNextArticle(articleId); */
} catch (final RepositoryException e) { public JSONObject getNextArticle(final String articleId) throws ServiceException {
LOGGER.log(Level.SEVERE, "Gets the next article failed[articleId=" + articleId + "]", e); try {
throw new ServiceException(e); return articleRepository.getNextArticle(articleId);
} } catch (final RepositoryException e) {
} LOGGER.log(Level.SEVERE, "Gets the next article failed[articleId=" + articleId + "]", e);
throw new ServiceException(e);
/** }
* Gets the previous article(by create date) by the specified article id. }
*
* <p> /**
* <b>Note</b>: The article content and abstract is raw (no editor type processing). * Gets the previous article(by create date) by the specified article id.
* </p> *
* * <p>
* @param articleId the specified article id * <b>Note</b>: The article content and abstract is raw (no editor type processing).
* @return the previous article, * </p>
* <pre> *
* { * @param articleId the specified article id
* "articleTitle": "", * @return the previous article,
* "articlePermalink": "" * <pre>
* } * {
* </pre> * "articleTitle": "",
* returns {@code null} if not found * "articlePermalink": ""
* @throws ServiceException service exception * }
*/ * </pre>
public JSONObject getPreviousArticle(final String articleId) throws ServiceException { * returns {@code null} if not found
try { * @throws ServiceException service exception
return articleRepository.getPreviousArticle(articleId); */
} catch (final RepositoryException e) { public JSONObject getPreviousArticle(final String articleId) throws ServiceException {
LOGGER.log(Level.SEVERE, "Gets the previous article failed[articleId=" + articleId + "]", e); try {
throw new ServiceException(e); return articleRepository.getPreviousArticle(articleId);
} } catch (final RepositoryException e) {
} LOGGER.log(Level.SEVERE, "Gets the previous article failed[articleId=" + articleId + "]", e);
throw new ServiceException(e);
/** }
* Gets an article by the specified article id. }
*
* <p> /**
* <b>Note</b>: The article content and abstract is raw (no editor type processing). * Gets an article by the specified article id.
* </p> *
* * <p>
* @param articleId the specified article id * <b>Note</b>: The article content and abstract is raw (no editor type processing).
* @return an article, returns {@code null} if not found * </p>
* @throws ServiceException service exception *
*/ * @param articleId the specified article id
public JSONObject getArticleById(final String articleId) throws ServiceException { * @return an article, returns {@code null} if not found
try { * @throws ServiceException service exception
return articleRepository.get(articleId); */
} catch (final RepositoryException e) { public JSONObject getArticleById(final String articleId) throws ServiceException {
LOGGER.log(Level.SEVERE, "Gets an article[articleId=" + articleId + "] failed", e); try {
throw new ServiceException(e); return articleRepository.get(articleId);
} } catch (final RepositoryException e) {
} LOGGER.log(Level.SEVERE, "Gets an article[articleId=" + articleId + "] failed", e);
throw new ServiceException(e);
/** }
* Gets <em>published</em> articles by the specified author email, current page number and page size. }
*
* @param authorEmail the specified author email /**
* @param currentPageNum the specified current page number * Gets <em>published</em> articles by the specified author email, current page number and page size.
* @param pageSize the specified page size *
* @return a list of articles, returns an empty list if not found * @param authorEmail the specified author email
* @throws ServiceException service exception * @param currentPageNum the specified current page number
*/ * @param pageSize the specified page size
public List<JSONObject> getArticlesByAuthorEmail(final String authorEmail, final int currentPageNum, final int pageSize) * @return a list of articles, returns an empty list if not found
throws ServiceException { * @throws ServiceException service exception
try { */
final JSONObject result = articleRepository.getByAuthorEmail(authorEmail, currentPageNum, pageSize); public List<JSONObject> getArticlesByAuthorEmail(final String authorEmail, final int currentPageNum, final int pageSize)
final JSONArray articles = result.getJSONArray(Keys.RESULTS); throws ServiceException {
final List<JSONObject> ret = new ArrayList<JSONObject>(); try {
final JSONObject result = articleRepository.getByAuthorEmail(authorEmail, currentPageNum, pageSize);
for (int i = 0; i < articles.length(); i++) { final JSONArray articles = result.getJSONArray(Keys.RESULTS);
final JSONObject article = articles.getJSONObject(i); final List<JSONObject> ret = new ArrayList<JSONObject>();
// Markdown to HTML for content and abstract for (int i = 0; i < articles.length(); i++) {
markdown(article); final JSONObject article = articles.getJSONObject(i);
ret.add(article); // Markdown to HTML for content and abstract
} markdown(article);
return ret; ret.add(article);
} catch (final Exception e) { }
LOGGER.log(Level.SEVERE, "Gets articles by author email failed[authorEmail="
+ authorEmail + ", currentPageNum=" + currentPageNum + ", pageSize=" + pageSize + "]", e); return ret;
} catch (final Exception e) {
throw new ServiceException(e); LOGGER.log(Level.SEVERE, "Gets articles by author email failed[authorEmail="
} + authorEmail + ", currentPageNum=" + currentPageNum + ", pageSize=" + pageSize + "]", e);
}
throw new ServiceException(e);
/** }
* Gets article contents with the specified article id. }
*
* <p> /**
* Invoking this method dose not effect on article view count. * Gets article contents with the specified article id.
* </p> *
* * <p>
* @param articleId the specified article id * Invoking this method dose not effect on article view count.
* @return article contents, returns {@code null} if not found * </p>
* @throws ServiceException service exception *
*/ * @param articleId the specified article id
public String getArticleContent(final String articleId) throws ServiceException { * @return article contents, returns {@code null} if not found
if (Strings.isEmptyOrNull(articleId)) { * @throws ServiceException service exception
return null; */
} public String getArticleContent(final String articleId) throws ServiceException {
if (Strings.isEmptyOrNull(articleId)) {
try { return null;
final JSONObject article = articleRepository.get(articleId); }
if (null == article) {
return null; try {
} final JSONObject article = articleRepository.get(articleId);
if (null == article) {
// Markdown to HTML for content and abstract return null;
if ("CodeMirror-Markdown".equals(article.optString(ARTICLE_EDITOR_TYPE))) { }
Stopwatchs.start("Get Article Content [Markdown]");
final String content = article.optString(ARTICLE_CONTENT); // Markdown to HTML for content and abstract
article.put(ARTICLE_CONTENT, Markdowns.toHTML(content)); if ("CodeMirror-Markdown".equals(article.optString(ARTICLE_EDITOR_TYPE))) {
Stopwatchs.end(); Stopwatchs.start("Get Article Content [Markdown]");
} final String content = article.optString(ARTICLE_CONTENT);
article.put(ARTICLE_CONTENT, Markdowns.toHTML(content));
return article.getString(Article.ARTICLE_CONTENT); Stopwatchs.end();
} catch (final Exception e) { }
LOGGER.log(Level.SEVERE, "Gets article content failed[articleId=" + articleId + "]", e);
return article.getString(Article.ARTICLE_CONTENT);
throw new ServiceException(e); } catch (final Exception e) {
} LOGGER.log(Level.SEVERE, "Gets article content failed[articleId=" + articleId + "]", e);
}
throw new ServiceException(e);
/** }
* Converts the content and abstract for each of the specified articles to HTML if that is saved by Markdown editor. }
*
* @param articles the specified articles /**
* @throws Exception exception * Converts the content and abstract for each of the specified articles to HTML if that is saved by Markdown editor.
*/ *
public void markdowns(final List<JSONObject> articles) throws Exception { * @param articles the specified articles
for (final JSONObject article : articles) { * @throws Exception exception
markdown(article); */
} public void markdowns(final List<JSONObject> articles) throws Exception {
} for (final JSONObject article : articles) {
markdown(article);
/** }
* Converts the content and abstract for the specified article to HTML if it is saved by Markdown editor. }
*
* @param article the specified article /**
* @throws Exception exception * Converts the content and abstract for the specified article to HTML if it is saved by Markdown editor.
*/ *
public void markdown(final JSONObject article) throws Exception { * @param article the specified article
if ("CodeMirror-Markdown".equals(article.optString(ARTICLE_EDITOR_TYPE))) { * @throws Exception exception
Stopwatchs.start("Markdown Article[id=" + article.optString(Keys.OBJECT_ID) + "]"); */
public void markdown(final JSONObject article) throws Exception {
Stopwatchs.start("Content"); if ("CodeMirror-Markdown".equals(article.optString(ARTICLE_EDITOR_TYPE))) {
final String content = article.optString(ARTICLE_CONTENT); Stopwatchs.start("Markdown Article[id=" + article.optString(Keys.OBJECT_ID) + "]");
article.put(ARTICLE_CONTENT, Markdowns.toHTML(content));
Stopwatchs.end(); Stopwatchs.start("Content");
final String content = article.optString(ARTICLE_CONTENT);
final String abstractContent = article.optString(ARTICLE_ABSTRACT); article.put(ARTICLE_CONTENT, Markdowns.toHTML(content));
if (!Strings.isEmptyOrNull(abstractContent)) { Stopwatchs.end();
Stopwatchs.start("Abstract");
article.put(ARTICLE_ABSTRACT, Markdowns.toHTML(abstractContent)); final String abstractContent = article.optString(ARTICLE_ABSTRACT);
Stopwatchs.end(); if (!Strings.isEmptyOrNull(abstractContent)) {
} Stopwatchs.start("Abstract");
article.put(ARTICLE_ABSTRACT, Markdowns.toHTML(abstractContent));
Stopwatchs.end(); Stopwatchs.end();
} }
}
Stopwatchs.end();
/** }
* Removes unused properties of each article in the specified articles. }
*
* <p> /**
* Remains the following properties: * Removes unused properties of each article in the specified articles.
* <ul> *
* <li>{@link Article#ARTICLE_TITLE article title}</li> * <p>
* <li>{@link Article#ARTICLE_PERMALINK article permalink}</li> * Remains the following properties:
* </ul> * <ul>
* </p> * <li>{@link Article#ARTICLE_TITLE article title}</li>
* * <li>{@link Article#ARTICLE_PERMALINK article permalink}</li>
* <p> * </ul>
* The batch version of method {@link #removeUnusedProperties(org.json.JSONObject)}. * </p>
* </p> *
* * <p>
* @param articles the specified articles * The batch version of method {@link #removeUnusedProperties(org.json.JSONObject)}.
* @see #removeUnusedProperties(org.json.JSONObject) * </p>
*/ *
public void removeUnusedProperties(final List<JSONObject> articles) { * @param articles the specified articles
for (final JSONObject article : articles) { * @see #removeUnusedProperties(org.json.JSONObject)
removeUnusedProperties(article); */
} public void removeUnusedProperties(final List<JSONObject> articles) {
} for (final JSONObject article : articles) {
removeUnusedProperties(article);
/** }
* Removes unused properties of the specified article. }
*
* <p> /**
* Remains the following properties: * Removes unused properties of the specified article.
* <ul> *
* <li>{@link Article#ARTICLE_TITLE article title}</li> * <p>
* <li>{@link Article#ARTICLE_PERMALINK article permalink}</li> * Remains the following properties:
* </ul> * <ul>
* </p> * <li>{@link Article#ARTICLE_TITLE article title}</li>
* * <li>{@link Article#ARTICLE_PERMALINK article permalink}</li>
* @param article the specified article * </ul>
* @see #removeUnusedProperties(java.util.List) * </p>
*/ *
public void removeUnusedProperties(final JSONObject article) { * @param article the specified article
article.remove(Keys.OBJECT_ID); * @see #removeUnusedProperties(java.util.List)
article.remove(Article.ARTICLE_AUTHOR_EMAIL); */
article.remove(Article.ARTICLE_ABSTRACT); public void removeUnusedProperties(final JSONObject article) {
article.remove(Article.ARTICLE_COMMENT_COUNT); article.remove(Keys.OBJECT_ID);
article.remove(Article.ARTICLE_CONTENT); article.remove(Article.ARTICLE_AUTHOR_EMAIL);
article.remove(Article.ARTICLE_CREATE_DATE); article.remove(Article.ARTICLE_ABSTRACT);
article.remove(Article.ARTICLE_TAGS_REF); article.remove(Article.ARTICLE_COMMENT_COUNT);
article.remove(Article.ARTICLE_UPDATE_DATE); article.remove(Article.ARTICLE_CONTENT);
article.remove(Article.ARTICLE_VIEW_COUNT); article.remove(Article.ARTICLE_CREATE_DATE);
article.remove(Article.ARTICLE_RANDOM_DOUBLE); article.remove(Article.ARTICLE_TAGS_REF);
article.remove(Article.ARTICLE_IS_PUBLISHED); article.remove(Article.ARTICLE_UPDATE_DATE);
article.remove(Article.ARTICLE_PUT_TOP); article.remove(Article.ARTICLE_VIEW_COUNT);
article.remove(Article.ARTICLE_HAD_BEEN_PUBLISHED); article.remove(Article.ARTICLE_RANDOM_DOUBLE);
} article.remove(Article.ARTICLE_IS_PUBLISHED);
article.remove(Article.ARTICLE_PUT_TOP);
/** article.remove(Article.ARTICLE_HAD_BEEN_PUBLISHED);
* Gets the {@link ArticleQueryService} singleton. }
*
* @return the singleton /**
*/ * Gets the {@link ArticleQueryService} singleton.
public static ArticleQueryService getInstance() { *
return SingletonHolder.SINGLETON; * @return the singleton
} */
public static ArticleQueryService getInstance() {
/** return SingletonHolder.SINGLETON;
* Private constructor. }
*/
private ArticleQueryService() { /**
} * Private constructor.
*/
/** private ArticleQueryService() {
* Singleton holder. }
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> /**
* @version 1.0.0.0, Oct 3, 2011 * Singleton holder.
*/ *
private static final class SingletonHolder { * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.0, Oct 3, 2011
/** */
* Singleton. private static final class SingletonHolder {
*/
private static final ArticleQueryService SINGLETON = new ArticleQueryService(); /**
* Singleton.
/** */
* Private default constructor. private static final ArticleQueryService SINGLETON = new ArticleQueryService();
*/
private SingletonHolder() { /**
} * Private default constructor.
} */
} private SingletonHolder() {
}
}
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.util; package org.b3log.solo.util;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.b3log.solo.model.Article; import org.b3log.solo.model.Article;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.repository.FilterOperator; import org.b3log.latke.repository.*;
import org.b3log.latke.repository.Query; import org.b3log.latke.service.ServiceException;
import org.b3log.latke.repository.RepositoryException; import org.b3log.latke.user.UserService;
import org.b3log.latke.repository.SortDirection; import org.b3log.latke.user.UserServiceFactory;
import org.b3log.latke.service.ServiceException; import org.b3log.latke.util.CollectionUtils;
import org.b3log.latke.user.UserService; import org.b3log.latke.util.Strings;
import org.b3log.latke.user.UserServiceFactory; import org.b3log.solo.model.Common;
import org.b3log.latke.util.CollectionUtils; import org.b3log.solo.model.Preference;
import org.b3log.latke.util.Strings; import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.model.Common; import org.b3log.solo.repository.UserRepository;
import org.b3log.solo.model.Preference; import org.b3log.solo.repository.impl.ArticleRepositoryImpl;
import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.repository.impl.UserRepositoryImpl;
import org.b3log.solo.repository.UserRepository; import org.json.JSONArray;
import org.b3log.solo.repository.impl.ArticleRepositoryImpl; import org.json.JSONException;
import org.b3log.solo.repository.impl.UserRepositoryImpl; import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException; /**
import org.json.JSONObject; * Article utilities.
*
/** * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* Article utilities. * @version 1.0.2.8, May 6, 2012
* * @since 0.3.1
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> */
* @version 1.0.2.8, May 6, 2012 public final class Articles {
* @since 0.3.1
*/ /**
public final class Articles { * Logger.
*/
/** private static final Logger LOGGER = Logger.getLogger(Articles.class.getName());
* Logger. /**
*/ * Article repository.
private static final Logger LOGGER = Logger.getLogger(Articles.class.getName()); */
/** private ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance();
* Article repository. /**
*/ * User repository.
private ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance(); */
/** private UserRepository userRepository = UserRepositoryImpl.getInstance();
* User repository. /**
*/ * User service.
private UserRepository userRepository = UserRepositoryImpl.getInstance(); */
/** private UserService userService = UserServiceFactory.getUserService();
* User service.
*/ /**
private UserService userService = UserServiceFactory.getUserService(); * Builds article view password form parameters with the specified article.
*
/** * @param article the specified article
* Builds article view password form parameters with the specified article. * @return parameters string, for example,
* * <pre>
* @param article the specified article * "?articleId=xxx&articleTitle=xxx&articlePermalink=xxx&articleAbstract=xxx"
* @return parameters string, for example, * </pre>
* <pre> * @throws UnsupportedEncodingException if can not encode the arguments
* "?articleId=xxx&articleTitle=xxx&articlePermalink=xxx&articleAbstract=xxx" */
* </pre> public String buildArticleViewPwdFormParameters(final JSONObject article) throws UnsupportedEncodingException {
* @throws UnsupportedEncodingException if can not encode the arguments final StringBuilder parametersBuilder =
*/ new StringBuilder("?articleId=").append(article.optString(Keys.OBJECT_ID)).
public String buildArticleViewPwdFormParameters(final JSONObject article) throws UnsupportedEncodingException { append("&articleTitle=").append(URLEncoder.encode(article.optString(Article.ARTICLE_TITLE), "UTF-8")).
final StringBuilder parametersBuilder = append("&articlePermalink=").append(URLEncoder.encode(article.optString(Article.ARTICLE_PERMALINK), "UTF-8")).
new StringBuilder("?articleId=").append(article.optString(Keys.OBJECT_ID)). append("&articleAbstract=").append(URLEncoder.encode(article.optString(Article.ARTICLE_ABSTRACT, " "), "UTF-8"));
append("&articleTitle=").append(URLEncoder.encode(article.optString(Article.ARTICLE_TITLE), "UTF-8")).
append("&articlePermalink=").append(URLEncoder.encode(article.optString(Article.ARTICLE_PERMALINK), "UTF-8")). return parametersBuilder.toString();
append("&articleAbstract=").append(URLEncoder.encode(article.optString(Article.ARTICLE_ABSTRACT, " "), "UTF-8")); }
return parametersBuilder.toString(); /**
} * Checks whether need password to view the specified article with the specified request.
*
/** * <p>
* Checks whether need password to view the specified article with the specified request. * Checks session, if not represents, checks article property {@link Article#ARTICLE_VIEW_PWD view password}.
* * </p>
* <p> *
* Checks session, if not represents, checks article property {@link Article#ARTICLE_VIEW_PWD view password}. * <p>
* </p> * The blogger itself dose not need view password never.
* * </p>
* <p> *
* The blogger itself dose not need view password never. * @param request the specified request
* </p> * @param article the specified article
* * @return {@code true} if need, returns {@code false} otherwise
* @param request the specified request */
* @param article the specified article public boolean needViewPwd(final HttpServletRequest request, final JSONObject article) {
* @return {@code true} if need, returns {@code false} otherwise final String articleViewPwd = article.optString(Article.ARTICLE_VIEW_PWD);
*/
public boolean needViewPwd(final HttpServletRequest request, final JSONObject article) { if (Strings.isEmptyOrNull(articleViewPwd)) {
final String articleViewPwd = article.optString(Article.ARTICLE_VIEW_PWD); return false;
}
if (Strings.isEmptyOrNull(articleViewPwd)) {
return false; final HttpSession session = request.getSession(false);
} if (null != session) {
@SuppressWarnings("unchecked")
final HttpSession session = request.getSession(false); Map<String, String> viewPwds = (Map<String, String>) session.getAttribute(Common.ARTICLES_VIEW_PWD);
if (null != session) { if (null == viewPwds) {
@SuppressWarnings("unchecked") viewPwds = new HashMap<String, String>();
Map<String, String> viewPwds = (Map<String, String>) session.getAttribute(Common.ARTICLES_VIEW_PWD); }
if (null == viewPwds) {
viewPwds = new HashMap<String, String>(); if (articleViewPwd.equals(viewPwds.get(article.optString(Keys.OBJECT_ID)))) {
} return false;
}
if (articleViewPwd.equals(viewPwds.get(article.optString(Keys.OBJECT_ID)))) { }
return false;
} if (null != userService.getCurrentUser(request)) {
} return false;
}
if (null != userService.getCurrentUser(request)) {
return false; return true;
} }
return true; /**
} * Gets the specified article's author.
*
/** * <p>
* Gets the specified article's author. * The specified article has a property
* * {@value Article#ARTICLE_AUTHOR_EMAIL}, this method will use this property
* <p> * to get a user from users.
* The specified article has a property * </p>
* {@value Article#ARTICLE_AUTHOR_EMAIL}, this method will use this property *
* to get a user from users. * <p>
* </p> * If can't find the specified article's author (i.e. the author has been
* * removed by administrator), returns administrator.
* <p> * </p>
* If can't find the specified article's author (i.e. the author has been *
* removed by administrator), returns administrator. * @param article the specified article
* </p> * @return user, {@code null} if not found
* * @throws ServiceException service exception
* @param article the specified article */
* @return user, {@code null} if not found public JSONObject getAuthor(final JSONObject article) throws ServiceException {
* @throws ServiceException service exception try {
*/ final String email = article.getString(Article.ARTICLE_AUTHOR_EMAIL);
public JSONObject getAuthor(final JSONObject article) throws ServiceException {
try { JSONObject ret = userRepository.getByEmail(email);
final String email = article.getString(Article.ARTICLE_AUTHOR_EMAIL);
if (null == ret) {
JSONObject ret = userRepository.getByEmail(email); LOGGER.log(Level.WARNING,
"Gets author of article failed, assumes the administrator is the author of this article[id={0}]",
if (null == ret) { article.getString(Keys.OBJECT_ID));
LOGGER.log(Level.WARNING, // This author may be deleted by admin, use admin as the author
"Gets author of article failed, assumes the administrator is the author of this article[id={0}]", // of this article
article.getString(Keys.OBJECT_ID)); ret = userRepository.getAdmin();
// This author may be deleted by admin, use admin as the author }
// of this article
ret = userRepository.getAdmin(); return ret;
} } catch (final RepositoryException e) {
LOGGER.log(Level.SEVERE, "Gets author of article[id={0}] failed", article.optString(Keys.OBJECT_ID));
return ret; throw new ServiceException(e);
} catch (final RepositoryException e) { } catch (final JSONException e) {
LOGGER.log(Level.SEVERE, "Gets author of article[id={0}] failed", article.optString(Keys.OBJECT_ID)); LOGGER.log(Level.SEVERE, "Gets author of article[id={0}] failed", article.optString(Keys.OBJECT_ID));
throw new ServiceException(e); throw new ServiceException(e);
} catch (final JSONException e) { }
LOGGER.log(Level.SEVERE, "Gets author of article[id={0}] failed", article.optString(Keys.OBJECT_ID)); }
throw new ServiceException(e);
} /**
} * Article comment count +1 for an article specified by the given article id.
*
/** * @param articleId the given article id
* Article comment count +1 for an article specified by the given article id. * @throws JSONException json exception
* * @throws RepositoryException repository exception
* @param articleId the given article id */
* @throws JSONException json exception public void incArticleCommentCount(final String articleId) throws JSONException, RepositoryException {
* @throws RepositoryException repository exception final JSONObject article = articleRepository.get(articleId);
*/ final JSONObject newArticle = new JSONObject(article, JSONObject.getNames(article));
public void incArticleCommentCount(final String articleId) throws JSONException, RepositoryException { final int commentCnt = article.getInt(Article.ARTICLE_COMMENT_COUNT);
final JSONObject article = articleRepository.get(articleId); newArticle.put(Article.ARTICLE_COMMENT_COUNT, commentCnt + 1);
final JSONObject newArticle = new JSONObject(article, JSONObject.getNames(article));
final int commentCnt = article.getInt(Article.ARTICLE_COMMENT_COUNT); articleRepository.update(articleId, newArticle);
newArticle.put(Article.ARTICLE_COMMENT_COUNT, commentCnt + 1); }
articleRepository.update(articleId, newArticle); /**
} * Gets the sign of an article specified by the sign id.
*
/** * @param signId the specified article id
* Gets the sign of an article specified by the sign id. * @param preference the specified preference
* * @return article sign, returns the default sign (which oId is "1") if not found
* @param signId the specified article id * @throws RepositoryException repository exception
* @param preference the specified preference * @throws JSONException json exception
* @return article sign, returns the default sign (which oId is "1") if not found */
* @throws RepositoryException repository exception public JSONObject getSign(final String signId, final JSONObject preference) throws JSONException, RepositoryException {
* @throws JSONException json exception final JSONArray signs = new JSONArray(preference.getString(Preference.SIGNS));
*/
public JSONObject getSign(final String signId, final JSONObject preference) throws JSONException, RepositoryException { JSONObject defaultSign = null;
final JSONArray signs = new JSONArray(preference.getString(Preference.SIGNS)); for (int i = 0; i < signs.length(); i++) {
final JSONObject ret = signs.getJSONObject(i);
JSONObject defaultSign = null; if (signId.equals(ret.optString(Keys.OBJECT_ID))) {
for (int i = 0; i < signs.length(); i++) { return ret;
final JSONObject ret = signs.getJSONObject(i); }
if (signId.equals(ret.optString(Keys.OBJECT_ID))) {
return ret; if ("1".equals(ret.optString(Keys.OBJECT_ID))) {
} defaultSign = ret;
}
if ("1".equals(ret.optString(Keys.OBJECT_ID))) { }
defaultSign = ret;
} LOGGER.log(Level.WARNING, "Can not find the sign[id={0}], returns a default sign[id=1]", signId);
} if (null == defaultSign) {
throw new IllegalStateException("Can not find the default sign which id equals to 1");
LOGGER.log(Level.WARNING, "Can not find the sign[id={0}], returns a default sign[id=1]", signId); }
if (null == defaultSign) {
throw new IllegalStateException("Can not find the default sign which id equals to 1"); return defaultSign;
} }
return defaultSign; /**
} * Determines the specified article has updated.
*
/** * @param article the specified article
* Determines the specified article has updated. * @return {@code true} if it has updated, {@code false} otherwise
* * @throws JSONException json exception
* @param article the specified article */
* @return {@code true} if it has updated, {@code false} otherwise public boolean hasUpdated(final JSONObject article) throws JSONException {
* @throws JSONException json exception final Date updateDate = (Date) article.get(Article.ARTICLE_UPDATE_DATE);
*/ final Date createDate = (Date) article.get(Article.ARTICLE_CREATE_DATE);
public boolean hasUpdated(final JSONObject article) throws JSONException {
final Date updateDate = (Date) article.get(Article.ARTICLE_UPDATE_DATE); return !createDate.equals(updateDate);
final Date createDate = (Date) article.get(Article.ARTICLE_CREATE_DATE); }
return !createDate.equals(updateDate); /**
} * Determines the specified article had been published.
*
/** * @param article the specified article
* Determines the specified article had been published. * @return {@code true} if it had been published, {@code false} otherwise
* * @throws JSONException json exception
* @param article the specified article */
* @return {@code true} if it had been published, {@code false} otherwise public boolean hadBeenPublished(final JSONObject article) throws JSONException {
* @throws JSONException json exception return article.getBoolean(Article.ARTICLE_HAD_BEEN_PUBLISHED);
*/ }
public boolean hadBeenPublished(final JSONObject article) throws JSONException {
return article.getBoolean(Article.ARTICLE_HAD_BEEN_PUBLISHED); /**
} * Gets all unpublished articles.
*
/** * @return articles all unpublished articles
* Gets all unpublished articles. * @throws RepositoryException repository exception
* * @throws JSONException json exception
* @return articles all unpublished articles */
* @throws RepositoryException repository exception public List<JSONObject> getUnpublishedArticles() throws RepositoryException, JSONException {
* @throws JSONException json exception final Map<String, SortDirection> sorts = new HashMap<String, SortDirection>();
*/ sorts.put(Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING);
public List<JSONObject> getUnpublishedArticles() throws RepositoryException, JSONException { sorts.put(Article.ARTICLE_PUT_TOP, SortDirection.DESCENDING);
final Map<String, SortDirection> sorts = new HashMap<String, SortDirection>(); final Query query = new Query().setFilter(
sorts.put(Article.ARTICLE_CREATE_DATE, SortDirection.DESCENDING); new PropertyFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true));
sorts.put(Article.ARTICLE_PUT_TOP, SortDirection.DESCENDING); final JSONObject result = articleRepository.get(query);
final Query query = new Query().addFilter(Article.ARTICLE_IS_PUBLISHED, FilterOperator.EQUAL, true); final JSONArray articles = result.getJSONArray(Keys.RESULTS);
final JSONObject result = articleRepository.get(query);
final JSONArray articles = result.getJSONArray(Keys.RESULTS); return CollectionUtils.jsonArrayToList(articles);
}
return CollectionUtils.jsonArrayToList(articles);
} /**
* Gets the {@link Articles} singleton.
/** *
* Gets the {@link Articles} singleton. * @return the singleton
* */
* @return the singleton public static Articles getInstance() {
*/ return SingletonHolder.SINGLETON;
public static Articles getInstance() { }
return SingletonHolder.SINGLETON;
} /**
* Private default constructor.
/** */
* Private default constructor. private Articles() {
*/ }
private Articles() {
} /**
* Singleton holder.
/** *
* Singleton holder. * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* * @version 1.0.0.0, Jan 12, 2011
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> */
* @version 1.0.0.0, Jan 12, 2011 private static final class SingletonHolder {
*/
private static final class SingletonHolder { /**
* Singleton.
/** */
* Singleton. private static final Articles SINGLETON = new Articles();
*/
private static final Articles SINGLETON = new Articles(); /**
* Private default constructor.
/** */
* Private default constructor. private SingletonHolder() {
*/ }
private SingletonHolder() { }
} }
}
}
/* /*
* Copyright (c) 2009, 2010, 2011, 2012, B3log Team * Copyright (c) 2009, 2010, 2011, 2012, B3log Team
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.b3log.solo.repository.impl; package org.b3log.solo.repository.impl;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.model.Role; import org.b3log.latke.model.Role;
import org.b3log.latke.model.User; import org.b3log.latke.model.User;
import org.b3log.latke.repository.FilterOperator; import org.b3log.latke.repository.FilterOperator;
import org.b3log.latke.repository.Query; import org.b3log.latke.repository.PropertyFilter;
import org.b3log.latke.repository.Transaction; import org.b3log.latke.repository.Query;
import org.b3log.solo.AbstractTestCase; import org.b3log.latke.repository.Transaction;
import org.b3log.solo.model.UserExt; import org.b3log.solo.AbstractTestCase;
import org.b3log.solo.repository.UserRepository; import org.b3log.solo.model.UserExt;
import org.json.JSONArray; import org.b3log.solo.repository.UserRepository;
import org.json.JSONObject; import org.json.JSONArray;
import org.testng.Assert; import org.json.JSONObject;
import org.testng.annotations.Test; import org.testng.Assert;
import org.testng.annotations.Test;
/**
* {@link UserRepositoryImpl} test case. /**
* * {@link UserRepositoryImpl} test case.
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> *
* @version 1.0.0.1, Feb 21, 2012 * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
*/ * @version 1.0.0.1, Feb 21, 2012
@Test(suiteName = "repository") */
public final class UserRepositoryImplTestCase extends AbstractTestCase { @Test(suiteName = "repository")
public final class UserRepositoryImplTestCase extends AbstractTestCase {
/**
* Tests. /**
* * Tests.
* @throws Exception exception *
*/ * @throws Exception exception
@Test */
public void test() throws Exception { @Test
final UserRepository userRepository = getUserRepository(); public void test() throws Exception {
final UserRepository userRepository = getUserRepository();
final JSONObject another = new JSONObject();
another.put(User.USER_NAME, "test1"); final JSONObject another = new JSONObject();
another.put(User.USER_EMAIL, "test1@gmail.com"); another.put(User.USER_NAME, "test1");
another.put(User.USER_PASSWORD, "pass1"); another.put(User.USER_EMAIL, "test1@gmail.com");
another.put(User.USER_ROLE, Role.DEFAULT_ROLE); another.put(User.USER_PASSWORD, "pass1");
another.put(UserExt.USER_ARTICLE_COUNT, 0); another.put(User.USER_ROLE, Role.DEFAULT_ROLE);
another.put(UserExt.USER_PUBLISHED_ARTICLE_COUNT, 0); another.put(UserExt.USER_ARTICLE_COUNT, 0);
another.put(UserExt.USER_PUBLISHED_ARTICLE_COUNT, 0);
Transaction transaction = userRepository.beginTransaction();
userRepository.add(another); Transaction transaction = userRepository.beginTransaction();
transaction.commit(); userRepository.add(another);
transaction.commit();
Assert.assertNull(userRepository.getAdmin());
Assert.assertNull(userRepository.getAdmin());
JSONObject admin = new JSONObject();
admin.put(User.USER_NAME, "test"); JSONObject admin = new JSONObject();
admin.put(User.USER_EMAIL, "test@gmail.com"); admin.put(User.USER_NAME, "test");
admin.put(User.USER_PASSWORD, "pass"); admin.put(User.USER_EMAIL, "test@gmail.com");
admin.put(User.USER_ROLE, Role.ADMIN_ROLE); admin.put(User.USER_PASSWORD, "pass");
admin.put(UserExt.USER_ARTICLE_COUNT, 0); admin.put(User.USER_ROLE, Role.ADMIN_ROLE);
admin.put(UserExt.USER_PUBLISHED_ARTICLE_COUNT, 0); admin.put(UserExt.USER_ARTICLE_COUNT, 0);
admin.put(UserExt.USER_PUBLISHED_ARTICLE_COUNT, 0);
transaction = userRepository.beginTransaction();
userRepository.add(admin); transaction = userRepository.beginTransaction();
transaction.commit(); userRepository.add(admin);
transaction.commit();
Assert.assertTrue(userRepository.isAdminEmail("test@gmail.com"));
Assert.assertFalse(userRepository.isAdminEmail("notFound@gmail.com")); Assert.assertTrue(userRepository.isAdminEmail("test@gmail.com"));
Assert.assertFalse(userRepository.isAdminEmail("notFound@gmail.com"));
admin = userRepository.getAdmin();
admin = userRepository.getAdmin();
Assert.assertNotNull(admin);
Assert.assertEquals("test", admin.optString(User.USER_NAME)); Assert.assertNotNull(admin);
Assert.assertEquals("test", admin.optString(User.USER_NAME));
final JSONObject result =
userRepository.get(new Query().addFilter(User.USER_NAME, final JSONObject result =
FilterOperator.EQUAL, userRepository.get(new Query().setFilter(
"test1")); new PropertyFilter(User.USER_NAME, FilterOperator.EQUAL, "test1")));
final JSONArray users = result.getJSONArray(Keys.RESULTS); final JSONArray users = result.getJSONArray(Keys.RESULTS);
Assert.assertEquals(users.length(), 1); Assert.assertEquals(users.length(), 1);
Assert.assertEquals(users.getJSONObject(0).getString(User.USER_EMAIL), Assert.assertEquals(users.getJSONObject(0).getString(User.USER_EMAIL),
"test1@gmail.com"); "test1@gmail.com");
final JSONObject notFound = final JSONObject notFound =
userRepository.getByEmail("not.found@gmail.com"); userRepository.getByEmail("not.found@gmail.com");
Assert.assertNull(notFound); Assert.assertNull(notFound);
final JSONObject found = userRepository.getByEmail("test1@gmail.com"); final JSONObject found = userRepository.getByEmail("test1@gmail.com");
Assert.assertNotNull(found); Assert.assertNotNull(found);
Assert.assertEquals(found.getString(User.USER_PASSWORD), "pass1"); Assert.assertEquals(found.getString(User.USER_PASSWORD), "pass1");
} }
} }
#
# Copyright (C) 2009, 2010, 2011, B3log Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# Description: ease skin (mock for test).
# Version: 1.0.0.0, Jun 27, 2012
# Author: Liang Ding
#
name=ease
version=1.0.1
forSolo=0.4.6
memo=\u56de\u5f52\u606c\u9759
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Description: B3log Solo parent POM. Description: B3log Solo parent POM.
Version: 2.0.2.0, Jun 19, 2012 Version: 2.0.2.1, Jun 27, 2012
Author: Liang Ding Author: Liang Ding
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
<org.b3log.latke.version>0.5.0-SNAPSHOT</org.b3log.latke.version> <org.b3log.latke.version>0.5.0-SNAPSHOT</org.b3log.latke.version>
<org.b3log.latke-gae.version>0.5.0-SNAPSHOT</org.b3log.latke-gae.version> <org.b3log.latke-gae.version>0.5.0-SNAPSHOT</org.b3log.latke-gae.version>
<org.b3log.latke-repository-mysql.version>0.5.0-SNAPSHOT</org.b3log.latke-repository-mysql.version> <org.b3log.latke-repository-mysql.version>0.5.0-SNAPSHOT</org.b3log.latke-repository-mysql.version>
<gae.version>1.6.5</gae.version> <gae.version>1.7.0</gae.version>
<freemarker-gae.version>2.3.19</freemarker-gae.version> <freemarker-gae.version>2.3.19</freemarker-gae.version>
<jsoup.version>1.5.2</jsoup.version> <jsoup.version>1.5.2</jsoup.version>
......
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