Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
solo
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
solo
Commits
2b112f73
Commit
2b112f73
authored
Mar 19, 2013
by
Liang Ding
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed #214
parent
bd5bbce7
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
650 additions
and
650 deletions
+650
-650
core/src/main/java/org/b3log/solo/api/metaweblog/MetaWeblogAPI.java
...ain/java/org/b3log/solo/api/metaweblog/MetaWeblogAPI.java
+650
-650
No files found.
core/src/main/java/org/b3log/solo/api/metaweblog/MetaWeblogAPI.java
View file @
2b112f73
/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
b3log
.
solo
.
api
.
metaweblog
;
import
java.text.ParseException
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
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.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.repository.impl.ArticleRepositoryImpl
;
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="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.
9, Jan 30, 2013
* @since 0.4.0
*/
@RequestProcessor
public
final
class
MetaWeblogAPI
{
/**
* Logger.
*/
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
MetaWeblogAPI
.
class
.
getName
());
/**
* Preference query service.
*/
private
PreferenceQueryService
preferenceQueryService
=
PreferenceQueryService
.
getInstance
();
/**
* Tag query service.
*/
private
TagQueryService
tagQueryService
=
TagQueryService
.
getInstance
();
/**
* Article query service.
*/
private
ArticleQueryService
articleQueryService
=
ArticleQueryService
.
getInstance
();
/**
* Article management service.
*/
private
ArticleMgmtService
articleMgmtService
=
ArticleMgmtService
.
getInstance
();
/**
* Article repository.
*/
private
ArticleRepository
articleRepository
=
ArticleRepositoryImpl
.
getInstance
();
/**
* User query service.
*/
private
UserQueryService
userQueryService
=
UserQueryService
.
getInstance
();
/**
* 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
.
SEVERE
,
e
.
getMessage
(),
e
);
responseContent
=
""
;
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
JSON
Array
params
=
methodCall
.
getJSONObject
(
"params"
).
getJSONArray
(
"param"
);
final
JSON
Object
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
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
final
String
dateString
=
member
.
getJSONObject
(
"value"
).
getString
(
"dateTime.iso8601"
);
Date
date
=
null
;
try
{
date
=
(
Date
)
DateFormatUtils
.
ISO_DATETIME_FORMAT
.
parseObject
(
dateString
);
}
catch
(
final
ParseException
e
)
{
LOGGER
.
log
(
Level
.
WARNING
,
"Parses article create date failed with ISO8601, retry to parse with pattern[yyyy-MM-dd'T'HH:mm:ss]"
);
date
=
DateUtils
.
parseDate
(
dateString
,
new
String
[]
{
"yyyyMMdd'T'HH:mm:ss"
});
}
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
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
final
String
categories
=
buildCategories
(
preference
);
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.
*
* @param preference the specified preference
* @return blog info XML
* @throws Exception exception
*/
private
String
buildCategories
(
final
JSONObject
preference
)
throws
Exception
{
final
String
blogHost
=
"http://"
+
preference
.
getString
(
Preference
.
BLOG_HOST
);
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
(
blogHost
).
append
(
"/tags/"
).
append
(
tagTitle
).
append
(
"</value></member>"
);
stringBuilder
.
append
(
"<member><name>rsslUrl</name>"
).
append
(
"<value>"
).
append
(
blogHost
).
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
String
blogURL
=
"http://"
+
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
StringBuilder
stringBuilder
=
new
StringBuilder
(
"<member><name>blogid</name><value>"
).
append
(
blogId
).
append
(
"</value></member>"
);
stringBuilder
.
append
(
"<member><name>url</name><value>"
).
append
(
blogURL
).
append
(
"</value></member>"
);
stringBuilder
.
append
(
"<member><name>blogName</name><value>"
).
append
(
blogTitle
).
append
(
"</value></member>"
);
return
stringBuilder
.
toString
();
}
}
/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, B3log Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
b3log
.
solo
.
api
.
metaweblog
;
import
java.text.ParseException
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
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.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.repository.impl.ArticleRepositoryImpl
;
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="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.
10, Mar 19, 2013
* @since 0.4.0
*/
@RequestProcessor
public
final
class
MetaWeblogAPI
{
/**
* Logger.
*/
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
MetaWeblogAPI
.
class
.
getName
());
/**
* Preference query service.
*/
private
PreferenceQueryService
preferenceQueryService
=
PreferenceQueryService
.
getInstance
();
/**
* Tag query service.
*/
private
TagQueryService
tagQueryService
=
TagQueryService
.
getInstance
();
/**
* Article query service.
*/
private
ArticleQueryService
articleQueryService
=
ArticleQueryService
.
getInstance
();
/**
* Article management service.
*/
private
ArticleMgmtService
articleMgmtService
=
ArticleMgmtService
.
getInstance
();
/**
* Article repository.
*/
private
ArticleRepository
articleRepository
=
ArticleRepositoryImpl
.
getInstance
();
/**
* User query service.
*/
private
UserQueryService
userQueryService
=
UserQueryService
.
getInstance
();
/**
* 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
.
SEVERE
,
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
JSON
Object
post
=
params
.
getJSONObject
(
INDEX_POST
).
getJSONObject
(
"value"
).
getJSONObject
(
"struct"
);
final
JSON
Array
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
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
final
String
dateString
=
member
.
getJSONObject
(
"value"
).
getString
(
"dateTime.iso8601"
);
Date
date
=
null
;
try
{
date
=
(
Date
)
DateFormatUtils
.
ISO_DATETIME_FORMAT
.
parseObject
(
dateString
);
}
catch
(
final
ParseException
e
)
{
LOGGER
.
log
(
Level
.
WARNING
,
"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
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
final
String
categories
=
buildCategories
(
preference
);
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.
*
* @param preference the specified preference
* @return blog info XML
* @throws Exception exception
*/
private
String
buildCategories
(
final
JSONObject
preference
)
throws
Exception
{
final
String
blogHost
=
"http://"
+
preference
.
getString
(
Preference
.
BLOG_HOST
);
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
(
blogHost
).
append
(
"/tags/"
).
append
(
tagTitle
).
append
(
"</value></member>"
);
stringBuilder
.
append
(
"<member><name>rsslUrl</name>"
).
append
(
"<value>"
).
append
(
blogHost
).
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
String
blogURL
=
"http://"
+
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
StringBuilder
stringBuilder
=
new
StringBuilder
(
"<member><name>blogid</name><value>"
).
append
(
blogId
).
append
(
"</value></member>"
);
stringBuilder
.
append
(
"<member><name>url</name><value>"
).
append
(
blogURL
).
append
(
"</value></member>"
);
stringBuilder
.
append
(
"<member><name>blogName</name><value>"
).
append
(
blogTitle
).
append
(
"</value></member>"
);
return
stringBuilder
.
toString
();
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment