首页>代码>Java开源博客系统框架B3log Solo源码下载>/b3log-solo-b3log-solo-0.6.8/core/src/main/java/org/b3log/solo/api/metaweblog/MetaWeblogAPI.java
/* * Copyright (c) 2010-2015, b3log.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.b3log.solo.api.metaweblog; import java.text.ParseException; import java.util.Date; import java.util.List; import javax.inject.Inject; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.time.DateFormatUtils; import org.apache.commons.lang.time.DateUtils; import org.b3log.latke.Keys; import org.b3log.latke.Latkes; import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Logger; import org.b3log.latke.model.User; import org.b3log.latke.repository.Transaction; import org.b3log.latke.service.ServiceException; import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.servlet.HTTPRequestMethod; import org.b3log.latke.servlet.annotation.RequestProcessing; import org.b3log.latke.servlet.annotation.RequestProcessor; import org.b3log.latke.servlet.renderer.TextXMLRenderer; import org.b3log.latke.util.MD5; import org.b3log.solo.model.Article; import org.b3log.solo.model.Preference; import org.b3log.solo.model.Tag; import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.service.ArticleMgmtService; import org.b3log.solo.service.ArticleQueryService; import org.b3log.solo.service.PreferenceQueryService; import org.b3log.solo.service.TagQueryService; import org.b3log.solo.service.UserQueryService; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.XML; import org.jsoup.Jsoup; /** * <a href="http://www.xmlrpc.com/metaWeblogApi">MetaWeblog API</a> requests processing. * * <p> * Implemented the following APIs: * <ul> * <li>blogger.deletePost</li> * <li>blogger.getUsersBlogs</li> * <li>metaWeblog.editPost</li> * <li>metaWeblog.getCategories</li> * <li>metaWeblog.getPost</li> * <li>metaWeblog.getRecentPosts</li> * <li>metaWeblog.newPost</li> * </ul> * </p> * * @author <a href="http://88250.b3log.org">Liang Ding</a> * @version 1.0.0.11, May 17, 2013 * @since 0.4.0 */ @RequestProcessor public class MetaWeblogAPI { /** * Logger. */ private static final Logger LOGGER = Logger.getLogger(MetaWeblogAPI.class.getName()); /** * Preference query service. */ @Inject private PreferenceQueryService preferenceQueryService; /** * Tag query service. */ @Inject private TagQueryService tagQueryService; /** * Article query service. */ @Inject private ArticleQueryService articleQueryService; /** * Article management service. */ @Inject private ArticleMgmtService articleMgmtService; /** * Article repository. */ @Inject private ArticleRepository articleRepository; /** * User query service. */ @Inject private UserQueryService userQueryService; /** * Key of method call. */ private static final String METHOD_CALL = "methodCall"; /** * Key of method name. */ private static final String METHOD_NAME = "methodName"; /** * Method name: "blogger.getUsersBlogs". */ private static final String METHOD_GET_USERS_BLOGS = "blogger.getUsersBlogs"; /** * Method name: "metaWeblog.getCategories". */ private static final String METHOD_GET_CATEGORIES = "metaWeblog.getCategories"; /** * Method name: "metaWeblog.getRecentPosts". */ private static final String METHOD_GET_RECENT_POSTS = "metaWeblog.getRecentPosts"; /** * Method name: "metaWeblog.newPost". */ private static final String METHOD_NEW_POST = "metaWeblog.newPost"; /** * Method name: "metaWeblog.editPost". */ private static final String METHOD_EDIT_POST = "metaWeblog.editPost"; /** * Method name: "metaWeblog.getPost". */ private static final String METHOD_GET_POST = "metaWeblog.getPost"; /** * Method name: "blogger.deletePost". */ private static final String METHOD_DELETE_POST = "blogger.deletePost"; /** * Argument "username" index. */ private static final int INDEX_USER_EMAIL = 1; /** * Argument "postid" index. */ private static final int INDEX_POST_ID = 0; /** * Argument "password" index. */ private static final int INDEX_USER_PWD = 2; /** * Argument "numberOfPosts" index. */ private static final int INDEX_NUM_OF_POSTS = 3; /** * Argument "post" index. */ private static final int INDEX_POST = 3; /** * Argument "publish" index. */ private static final int INDEX_PUBLISH = 4; /** * Article abstract length. */ private static final int ARTICLE_ABSTRACT_LENGTH = 500; /** * MetaWeblog requests processing. * * @param request the specified http servlet request * @param response the specified http servlet response * @param context the specified http request context */ @RequestProcessing(value = "/apis/metaweblog", method = HTTPRequestMethod.POST) public void metaWeblog(final HttpServletRequest request, final HttpServletResponse response, final HTTPRequestContext context) { final TextXMLRenderer renderer = new TextXMLRenderer(); context.setRenderer(renderer); String responseContent = null; try { final ServletInputStream inputStream = request.getInputStream(); final String xml = IOUtils.toString(inputStream, "UTF-8"); final JSONObject requestJSONObject = XML.toJSONObject(xml); final JSONObject methodCall = requestJSONObject.getJSONObject(METHOD_CALL); final String methodName = methodCall.getString(METHOD_NAME); LOGGER.log(Level.INFO, "MetaWeblog[methodName={0}]", methodName); final JSONArray params = methodCall.getJSONObject("params").getJSONArray("param"); if (METHOD_DELETE_POST.equals(methodName)) { params.remove(0); // Removes the first argument "appkey" } final String userEmail = params.getJSONObject(INDEX_USER_EMAIL).getJSONObject("value").getString("string"); final JSONObject user = userQueryService.getUserByEmail(userEmail); if (null == user) { throw new Exception("No user[email=" + userEmail + "]"); } final String userPwd = params.getJSONObject(INDEX_USER_PWD).getJSONObject("value").getString("string"); if (!user.getString(User.USER_PASSWORD).equals(MD5.hash(userPwd))) { throw new Exception("Wrong password"); } if (METHOD_GET_USERS_BLOGS.equals(methodName)) { responseContent = getUsersBlogs(); } else if (METHOD_GET_CATEGORIES.equals(methodName)) { responseContent = getCategories(); } else if (METHOD_GET_RECENT_POSTS.equals(methodName)) { final int numOfPosts = params.getJSONObject(INDEX_NUM_OF_POSTS).getJSONObject("value").getInt("int"); responseContent = getRecentPosts(numOfPosts); } else if (METHOD_NEW_POST.equals(methodName)) { final JSONObject article = parsetPost(methodCall); article.put(Article.ARTICLE_AUTHOR_EMAIL, userEmail); addArticle(article); final StringBuilder stringBuilder = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse>").append("<params><param><value><string>").append(article.getString(Keys.OBJECT_ID)).append( "</string></value></param></params></methodResponse>"); responseContent = stringBuilder.toString(); } else if (METHOD_GET_POST.equals(methodName)) { final String postId = params.getJSONObject(INDEX_POST_ID).getJSONObject("value").getString("string"); responseContent = getPost(postId); } else if (METHOD_EDIT_POST.equals(methodName)) { final JSONObject article = parsetPost(methodCall); final String postId = params.getJSONObject(INDEX_POST_ID).getJSONObject("value").getString("string"); article.put(Keys.OBJECT_ID, postId); article.put(Article.ARTICLE_AUTHOR_EMAIL, userEmail); final JSONObject updateArticleRequest = new JSONObject(); updateArticleRequest.put(Article.ARTICLE, article); articleMgmtService.updateArticle(updateArticleRequest); final StringBuilder stringBuilder = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse>").append("<params><param><value><string>").append(postId).append( "</string></value></param></params></methodResponse>"); responseContent = stringBuilder.toString(); } else if (METHOD_DELETE_POST.equals(methodName)) { final String postId = params.getJSONObject(INDEX_POST_ID).getJSONObject("value").getString("string"); articleMgmtService.removeArticle(postId); final StringBuilder stringBuilder = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse>").append("<params><param><value><boolean>").append(true).append( "</boolean></value></param></params></methodResponse>"); responseContent = stringBuilder.toString(); } else { throw new UnsupportedOperationException("Unsupported method[name=" + methodName + "]"); } } catch (final Exception e) { LOGGER.log(Level.ERROR, e.getMessage(), e); final StringBuilder stringBuilder = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse>").append("<fault><value><struct>").append("<member><name>faultCode</name><value><int>500</int></value></member>").append("<member><name>faultString</name><value><string>").append(e.getMessage()).append( "</string></value></member></struct></value></fault></methodResponse>"); responseContent = stringBuilder.toString(); } renderer.setContent(responseContent); } /** * Processes {@value #METHOD_GET_POST}. * * @param postId the specified post id * @return method response XML * @throws Exception exception */ private String getPost(final String postId) throws Exception { final StringBuilder stringBuilder = new StringBuilder( "<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse><params><param><value>"); final String posts = buildPost(postId); stringBuilder.append(posts); stringBuilder.append("</value></param></params></methodResponse>"); return stringBuilder.toString(); } /** * Adds the specified article. * * @param article the specified article * @throws Exception exception */ private void addArticle(final JSONObject article) throws Exception { final Transaction transaction = articleRepository.beginTransaction(); try { articleMgmtService.addArticleInternal(article); transaction.commit(); } catch (final ServiceException e) { if (transaction.isActive()) { transaction.rollback(); } throw e; } } /** * Parses the specified method call for an article. * * @param methodCall the specified method call * @return article * @throws Exception exception */ private JSONObject parsetPost(final JSONObject methodCall) throws Exception { final JSONObject ret = new JSONObject(); final JSONArray params = methodCall.getJSONObject("params").getJSONArray("param"); final JSONObject post = params.getJSONObject(INDEX_POST).getJSONObject("value").getJSONObject("struct"); final JSONArray members = post.getJSONArray("member"); for (int i = 0; i < members.length(); i++) { final JSONObject member = members.getJSONObject(i); final String name = member.getString("name"); if ("dateCreated".equals(name)) { final String dateString = member.getJSONObject("value").getString("dateTime.iso8601"); Date date; try { date = (Date) DateFormatUtils.ISO_DATETIME_FORMAT.parseObject(dateString); } catch (final ParseException e) { LOGGER.log(Level.WARN, "Parses article create date failed with ISO8601, retry to parse with " + "pattern[yyyy-MM-dd'T'HH:mm:ss, yyyyMMdd'T'HH:mm:ss'Z']"); date = DateUtils.parseDate(dateString, new String[] {"yyyyMMdd'T'HH:mm:ss", "yyyyMMdd'T'HH:mm:ss'Z'"}); } ret.put(Article.ARTICLE_CREATE_DATE, date); } else if ("title".equals(name)) { ret.put(Article.ARTICLE_TITLE, member.getJSONObject("value").getString("string")); } else if ("description".equals(name)) { final String content = member.getJSONObject("value").getString("string"); ret.put(Article.ARTICLE_CONTENT, content); final String plainTextContent = Jsoup.parse(content).text(); if (plainTextContent.length() > ARTICLE_ABSTRACT_LENGTH) { ret.put(Article.ARTICLE_ABSTRACT, plainTextContent.substring(0, ARTICLE_ABSTRACT_LENGTH)); } else { ret.put(Article.ARTICLE_ABSTRACT, plainTextContent); } } else if ("categories".equals(name)) { final StringBuilder tagBuilder = new StringBuilder(); final JSONObject data = member.getJSONObject("value").getJSONObject("array").getJSONObject("data"); if (0 == data.length()) { throw new Exception("At least one Tag"); } final Object value = data.get("value"); if (value instanceof JSONArray) { final JSONArray tags = (JSONArray) value; for (int j = 0; j < tags.length(); j++) { final String tagTitle = tags.getJSONObject(j).getString("string"); tagBuilder.append(tagTitle); if (j < tags.length() - 1) { tagBuilder.append(","); } } } else { final JSONObject tag = (JSONObject) value; tagBuilder.append(tag.getString("string")); } ret.put(Article.ARTICLE_TAGS_REF, tagBuilder.toString()); } } final boolean publish = 1 == params.getJSONObject(INDEX_PUBLISH).getJSONObject("value").getInt("boolean") ? true : false; ret.put(Article.ARTICLE_IS_PUBLISHED, publish); ret.put(Article.ARTICLE_COMMENTABLE, true); ret.put(Article.ARTICLE_VIEW_PWD, ""); return ret; } /** * Processes {@value #METHOD_GET_RECENT_POSTS}. * * @param fetchSize the specified fetch size * @return method response XML * @throws Exception exception */ private String getRecentPosts(final int fetchSize) throws Exception { final StringBuilder stringBuilder = new StringBuilder( "<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse><params><param><value><array><data>"); final String posts = buildRecentPosts(fetchSize); stringBuilder.append(posts); stringBuilder.append("</data></array></value></param></params></methodResponse>"); return stringBuilder.toString(); } /** * Processes {@value #METHOD_GET_CATEGORIES}. * * @return method response XML * @throws Exception exception */ private String getCategories() throws Exception { final StringBuilder stringBuilder = new StringBuilder( "<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse><params><param><value><array><data>"); final String categories = buildCategories(); stringBuilder.append(categories); stringBuilder.append("</data></array></value></param></params></methodResponse>"); return stringBuilder.toString(); } /** * Processes {@value #METHOD_GET_USERS_BLOGS}. * * @return method response XML * @throws Exception exception */ private String getUsersBlogs() throws Exception { final StringBuilder stringBuilder = new StringBuilder( "<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse><params><param><value><array><data><value><struct>"); final JSONObject preference = preferenceQueryService.getPreference(); final String blogInfo = buildBlogInfo(preference); stringBuilder.append(blogInfo); stringBuilder.append("</struct></value></data></array></value></param></params></methodResponse>"); return stringBuilder.toString(); } /** * Builds a post (post struct) with the specified post id. * * @param postId the specified post id * @return blog info XML * @throws Exception exception */ private String buildPost(final String postId) throws Exception { final StringBuilder stringBuilder = new StringBuilder(); final JSONObject result = articleQueryService.getArticle(postId); if (null == result) { throw new Exception("Not found article[id=" + postId + "]"); } final JSONObject article = result.getJSONObject(Article.ARTICLE); final Date createDate = (Date) article.get(Article.ARTICLE_CREATE_DATE); final String articleTitle = StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_TITLE)); stringBuilder.append("<struct>"); stringBuilder.append("<member><name>dateCreated</name>").append("<value><dateTime.iso8601>").append(DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(createDate)).append( "</dateTime.iso8601></value></member>"); stringBuilder.append("<member><name>description</name>").append("<value>").append(StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_CONTENT))).append( "</value></member>"); stringBuilder.append("<member><name>title</name>").append("<value>").append(articleTitle).append("</value></member>"); stringBuilder.append("<member><name>categories</name>").append("<value><array><data>"); final JSONArray tags = article.getJSONArray(Article.ARTICLE_TAGS_REF); for (int i = 0; i < tags.length(); i++) { final String tagTitle = tags.getJSONObject(i).getString(Tag.TAG_TITLE); stringBuilder.append("<value>").append(tagTitle).append("</value>"); } stringBuilder.append("</data></array></value></member></struct>"); return stringBuilder.toString(); } /** * Builds recent posts (array of post structs) with the specified * fetch size. * * @param fetchSize the specified fetch size * @return blog info XML * @throws Exception exception */ private String buildRecentPosts(final int fetchSize) throws Exception { final StringBuilder stringBuilder = new StringBuilder(); final List<JSONObject> recentArticles = articleQueryService.getRecentArticles(fetchSize); for (final JSONObject article : recentArticles) { final Date createDate = (Date) article.get(Article.ARTICLE_CREATE_DATE); final String articleTitle = StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_TITLE)); stringBuilder.append("<value><struct>"); stringBuilder.append("<member><name>dateCreated</name>").append("<value><dateTime.iso8601>").append(DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(createDate)).append( "</dateTime.iso8601></value></member>"); stringBuilder.append("<member><name>description</name>").append("<value>").append(StringEscapeUtils.escapeXml(article.getString(Article.ARTICLE_CONTENT))).append( "</value></member>"); stringBuilder.append("<member><name>title</name>").append("<value>").append(articleTitle).append("</value></member>"); stringBuilder.append("<member><name>postid</name>").append("<value>").append(article.getString(Keys.OBJECT_ID)).append( "</value></member>"); stringBuilder.append("<member><name>categories</name>").append("<value><array><data>"); final String tagTitles = article.getString(Article.ARTICLE_TAGS_REF); final String[] tagTitleArray = tagTitles.split(","); for (int i = 0; i < tagTitleArray.length; i++) { final String tagTitle = tagTitleArray[i]; stringBuilder.append("<value>").append(tagTitle).append("</value>"); } stringBuilder.append("</data></array></value></member>"); stringBuilder.append("</struct></value>"); } return stringBuilder.toString(); } /** * Builds categories (array of category info structs) with the specified preference. * * @return blog info XML * @throws Exception exception */ private String buildCategories() throws Exception { final StringBuilder stringBuilder = new StringBuilder(); final List<JSONObject> tags = tagQueryService.getTags(); for (final JSONObject tag : tags) { final String tagTitle = StringEscapeUtils.escapeXml(tag.getString(Tag.TAG_TITLE)); final String tagId = tag.getString(Keys.OBJECT_ID); stringBuilder.append("<value><struct>"); stringBuilder.append("<member><name>description</name>").append("<value>").append(tagTitle).append("</value></member>"); stringBuilder.append("<member><name>title</name>").append("<value>").append(tagTitle).append("</value></member>"); stringBuilder.append("<member><name>categoryid</name>").append("<value>").append(tagId).append("</value></member>"); stringBuilder.append("<member><name>htmlUrl</name>").append("<value>").append(Latkes.getServePath()).append("/tags/").append(tagTitle).append( "</value></member>"); stringBuilder.append("<member><name>rsslUrl</name>").append("<value>").append(Latkes.getServePath()).append("/tag-articles-rss.do?oId=").append(tagId).append( "</value></member>"); stringBuilder.append("</struct></value>"); } return stringBuilder.toString(); } /** * Builds blog info struct with the specified preference. * * @param preference the specified preference * @return blog info XML * @throws JSONException json exception */ private String buildBlogInfo(final JSONObject preference) throws JSONException { final String blogId = preference.getString(Keys.OBJECT_ID); final String blogTitle = StringEscapeUtils.escapeXml(preference.getString(Preference.BLOG_TITLE)); final StringBuilder stringBuilder = new StringBuilder("<member><name>blogid</name><value>").append(blogId).append( "</value></member>"); stringBuilder.append("<member><name>url</name><value>").append(Latkes.getServePath()).append("</value></member>"); stringBuilder.append("<member><name>blogName</name><value>").append(blogTitle).append("</value></member>"); return stringBuilder.toString(); } }
最近下载更多
微信网友_6717388559257600 LV1
2023年11月1日
cheung524071 LV8
2023年8月23日
yyyyzh LV1
2022年12月27日
疯子庭 LV8
2021年11月30日
云生123456 LV6
2021年6月8日
hehuiai1 LV2
2020年10月17日
qq2308261 LV2
2020年8月24日
庐州一生挚爱 LV3
2020年5月30日
471135409 LV1
2020年5月26日
cesare-blog LV6
2020年5月25日
最近浏览更多
davidlee2015 LV6
2023年11月19日
微信网友_6717388559257600 LV1
2023年11月1日
zhaobing_g LV3
2023年8月28日
cheung524071 LV8
2023年8月23日
wanglongfei2 LV2
2023年6月15日
不止是六位数 LV7
2023年3月21日
KevinST LV5
2023年2月6日
yyyyzh LV1
2022年12月27日
zxc131313 LV12
2022年11月21日
迷迭香 LV10
2022年9月21日