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
65f8a5e9
Commit
65f8a5e9
authored
Jun 27, 2012
by
Liang Ding
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed #34
升级 GAE SDK 到 1.7.0,Latke 中加入了对 OR 查询的支持。
parent
bd44f5d3
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
4915 additions
and
4915 deletions
+4915
-4915
core/src/main/java/org/b3log/solo/processor/FeedProcessor.java
...src/main/java/org/b3log/solo/processor/FeedProcessor.java
+515
-515
core/src/main/java/org/b3log/solo/processor/SitemapProcessor.java
.../main/java/org/b3log/solo/processor/SitemapProcessor.java
+242
-242
core/src/main/java/org/b3log/solo/processor/util/Filler.java
core/src/main/java/org/b3log/solo/processor/util/Filler.java
+901
-901
core/src/main/java/org/b3log/solo/repository/impl/ArchiveDateArticleRepositoryImpl.java
...olo/repository/impl/ArchiveDateArticleRepositoryImpl.java
+90
-90
core/src/main/java/org/b3log/solo/repository/impl/ArchiveDateRepositoryImpl.java
...b3log/solo/repository/impl/ArchiveDateRepositoryImpl.java
+124
-124
core/src/main/java/org/b3log/solo/repository/impl/ArticleRepositoryImpl.java
...org/b3log/solo/repository/impl/ArticleRepositoryImpl.java
+260
-260
core/src/main/java/org/b3log/solo/repository/impl/CommentRepositoryImpl.java
...org/b3log/solo/repository/impl/CommentRepositoryImpl.java
+168
-168
core/src/main/java/org/b3log/solo/repository/impl/LinkRepositoryImpl.java
...va/org/b3log/solo/repository/impl/LinkRepositoryImpl.java
+156
-156
core/src/main/java/org/b3log/solo/repository/impl/PageRepositoryImpl.java
...va/org/b3log/solo/repository/impl/PageRepositoryImpl.java
+161
-161
core/src/main/java/org/b3log/solo/repository/impl/TagArticleRepositoryImpl.java
.../b3log/solo/repository/impl/TagArticleRepositoryImpl.java
+91
-91
core/src/main/java/org/b3log/solo/repository/impl/TagRepositoryImpl.java
...ava/org/b3log/solo/repository/impl/TagRepositoryImpl.java
+115
-115
core/src/main/java/org/b3log/solo/repository/impl/UserRepositoryImpl.java
...va/org/b3log/solo/repository/impl/UserRepositoryImpl.java
+104
-104
core/src/main/java/org/b3log/solo/service/ArticleQueryService.java
...main/java/org/b3log/solo/service/ArticleQueryService.java
+806
-806
core/src/main/java/org/b3log/solo/util/Articles.java
core/src/main/java/org/b3log/solo/util/Articles.java
+305
-305
core/src/test/java/org/b3log/solo/repository/impl/UserRepositoryImplTestCase.java
...3log/solo/repository/impl/UserRepositoryImplTestCase.java
+102
-102
war/src/main/webapp/skins/ease/css/ease.css
war/src/main/webapp/skins/ease/css/ease.css
+666
-666
war/src/main/webapp/skins/ease/css/ease.min.css
war/src/main/webapp/skins/ease/css/ease.min.css
+109
-109
No files found.
core/src/main/java/org/b3log/solo/processor/FeedProcessor.java
View file @
65f8a5e9
/*
/*
* 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.Query
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.servlet.HTTPRequestContext
;
import
org.b3log.latke.servlet.HTTPRequestContext
;
import
org.b3log.latke.servlet.HTTPRequestMethod
;
import
org.b3log.latke.servlet.HTTPRequestMethod
;
import
org.b3log.latke.servlet.renderer.AtomRenderer
;
import
org.b3log.latke.servlet.renderer.AtomRenderer
;
import
org.b3log.latke.servlet.renderer.RssRenderer
;
import
org.b3log.latke.servlet.renderer.RssRenderer
;
import
org.b3log.latke.util.Locales
;
import
org.b3log.latke.util.Locales
;
import
org.b3log.latke.util.Strings
;
import
org.b3log.latke.util.Strings
;
import
org.b3log.solo.SoloServletListener
;
import
org.b3log.solo.SoloServletListener
;
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.model.Tag
;
import
org.b3log.solo.model.Tag
;
import
org.b3log.solo.model.feed.atom.Category
;
import
org.b3log.solo.model.feed.atom.Category
;
import
org.b3log.solo.model.feed.atom.Entry
;
import
org.b3log.solo.model.feed.atom.Entry
;
import
org.b3log.solo.model.feed.atom.Feed
;
import
org.b3log.solo.model.feed.atom.Feed
;
import
org.b3log.solo.model.feed.rss.Channel
;
import
org.b3log.solo.model.feed.rss.Channel
;
import
org.b3log.solo.model.feed.rss.Item
;
import
org.b3log.solo.model.feed.rss.Item
;
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.service.PreferenceQueryService
;
import
org.b3log.solo.service.PreferenceQueryService
;
import
org.b3log.solo.util.Articles
;
import
org.b3log.solo.util.Articles
;
import
org.b3log.solo.util.TimeZones
;
import
org.b3log.solo.util.TimeZones
;
import
org.b3log.solo.util.Users
;
import
org.b3log.solo.util.Users
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
/**
/**
* Feed (Atom/RSS) processor.
* Feed (Atom/RSS) processor.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.1.0.0, May 10, 2012
* @version 1.1.0.0, May 10, 2012
* @since 0.3.1
* @since 0.3.1
*/
*/
@RequestProcessor
@RequestProcessor
public
final
class
FeedProcessor
{
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
})
@RequestProcessing
(
value
=
{
"/blog-articles-feed.do"
},
method
=
{
HTTPRequestMethod
.
GET
,
HTTPRequestMethod
.
HEAD
})
public
void
blogArticlesAtom
(
final
HTTPRequestContext
context
)
{
public
void
blogArticlesAtom
(
final
HTTPRequestContext
context
)
{
final
AtomRenderer
renderer
=
new
AtomRenderer
();
final
AtomRenderer
renderer
=
new
AtomRenderer
();
context
.
setRenderer
(
renderer
);
context
.
setRenderer
(
renderer
);
final
Feed
feed
=
new
Feed
();
final
Feed
feed
=
new
Feed
();
try
{
try
{
final
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
final
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
final
String
blogTitle
=
preference
.
getString
(
Preference
.
BLOG_TITLE
);
final
String
blogTitle
=
preference
.
getString
(
Preference
.
BLOG_TITLE
);
final
String
blogSubtitle
=
preference
.
getString
(
Preference
.
BLOG_SUBTITLE
);
final
String
blogSubtitle
=
preference
.
getString
(
Preference
.
BLOG_SUBTITLE
);
final
String
blogHost
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
String
blogHost
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
feed
.
setTitle
(
StringEscapeUtils
.
escapeXml
(
blogTitle
));
feed
.
setTitle
(
StringEscapeUtils
.
escapeXml
(
blogTitle
));
feed
.
setSubtitle
(
StringEscapeUtils
.
escapeXml
(
blogSubtitle
));
feed
.
setSubtitle
(
StringEscapeUtils
.
escapeXml
(
blogSubtitle
));
feed
.
setUpdated
(
TimeZones
.
getTime
(
preference
.
getString
(
Preference
.
TIME_ZONE_ID
)));
feed
.
setUpdated
(
TimeZones
.
getTime
(
preference
.
getString
(
Preference
.
TIME_ZONE_ID
)));
feed
.
setAuthor
(
StringEscapeUtils
.
escapeXml
(
blogTitle
));
feed
.
setAuthor
(
StringEscapeUtils
.
escapeXml
(
blogTitle
));
feed
.
setLink
(
"http://"
+
blogHost
+
"/blog-articles-feed.do"
);
feed
.
setLink
(
"http://"
+
blogHost
+
"/blog-articles-feed.do"
);
feed
.
setId
(
"http://"
+
blogHost
+
"/"
);
feed
.
setId
(
"http://"
+
blogHost
+
"/"
);
final
Query
query
=
new
Query
().
setCurrentPageNum
(
1
).
final
Query
query
=
new
Query
().
setCurrentPageNum
(
1
).
setPageSize
(
ENTRY_OUTPUT_CNT
).
setPageSize
(
ENTRY_OUTPUT_CNT
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
).
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
).
setPageCount
(
1
);
setPageCount
(
1
);
final
boolean
hasMultipleUsers
=
Users
.
getInstance
().
hasMultipleUsers
();
final
boolean
hasMultipleUsers
=
Users
.
getInstance
().
hasMultipleUsers
();
String
authorName
=
""
;
String
authorName
=
""
;
final
JSONObject
articleResult
=
articleRepository
.
get
(
query
);
final
JSONObject
articleResult
=
articleRepository
.
get
(
query
);
final
JSONArray
articles
=
articleResult
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
articles
=
articleResult
.
getJSONArray
(
Keys
.
RESULTS
);
if
(!
hasMultipleUsers
&&
0
!=
articles
.
length
())
{
if
(!
hasMultipleUsers
&&
0
!=
articles
.
length
())
{
authorName
=
articleUtils
.
getAuthor
(
articles
.
getJSONObject
(
0
)).
getString
(
User
.
USER_NAME
);
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
++)
{
for
(
int
i
=
0
;
i
<
articles
.
length
();
i
++)
{
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
final
Entry
entry
=
new
Entry
();
final
Entry
entry
=
new
Entry
();
feed
.
addEntry
(
entry
);
feed
.
addEntry
(
entry
);
final
String
title
=
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_TITLE
));
final
String
title
=
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_TITLE
));
entry
.
setTitle
(
title
);
entry
.
setTitle
(
title
);
final
String
summary
=
isFullContent
?
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_CONTENT
))
final
String
summary
=
isFullContent
?
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_CONTENT
))
:
StringEscapeUtils
.
escapeXml
(
article
.
optString
(
Article
.
ARTICLE_ABSTRACT
));
:
StringEscapeUtils
.
escapeXml
(
article
.
optString
(
Article
.
ARTICLE_ABSTRACT
));
entry
.
setSummary
(
summary
);
entry
.
setSummary
(
summary
);
final
Date
updated
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_UPDATE_DATE
);
final
Date
updated
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_UPDATE_DATE
);
entry
.
setUpdated
(
updated
);
entry
.
setUpdated
(
updated
);
final
String
link
=
"http://"
+
blogHost
+
article
.
getString
(
Article
.
ARTICLE_PERMALINK
);
final
String
link
=
"http://"
+
blogHost
+
article
.
getString
(
Article
.
ARTICLE_PERMALINK
);
entry
.
setLink
(
link
);
entry
.
setLink
(
link
);
entry
.
setId
(
link
);
entry
.
setId
(
link
);
if
(
hasMultipleUsers
)
{
if
(
hasMultipleUsers
)
{
authorName
=
StringEscapeUtils
.
escapeXml
(
articleUtils
.
getAuthor
(
article
).
getString
(
User
.
USER_NAME
));
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
tagsString
=
article
.
getString
(
Article
.
ARTICLE_TAGS_REF
);
final
String
[]
tagStrings
=
tagsString
.
split
(
","
);
final
String
[]
tagStrings
=
tagsString
.
split
(
","
);
for
(
int
j
=
0
;
j
<
tagStrings
.
length
;
j
++)
{
for
(
int
j
=
0
;
j
<
tagStrings
.
length
;
j
++)
{
final
Category
catetory
=
new
Category
();
final
Category
catetory
=
new
Category
();
entry
.
addCatetory
(
catetory
);
entry
.
addCatetory
(
catetory
);
final
String
tag
=
tagStrings
[
j
];
final
String
tag
=
tagStrings
[
j
];
catetory
.
setTerm
(
tag
);
catetory
.
setTerm
(
tag
);
}
}
}
}
renderer
.
setContent
(
feed
.
toString
());
renderer
.
setContent
(
feed
.
toString
());
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Get blog article feed error"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Get blog article feed error"
,
e
);
try
{
try
{
context
.
getResponse
().
sendError
(
context
.
getResponse
().
sendError
(
HttpServletResponse
.
SC_SERVICE_UNAVAILABLE
);
HttpServletResponse
.
SC_SERVICE_UNAVAILABLE
);
}
catch
(
final
IOException
ex
)
{
}
catch
(
final
IOException
ex
)
{
throw
new
RuntimeException
(
ex
);
throw
new
RuntimeException
(
ex
);
}
}
}
}
}
}
/**
/**
* Tag articles Atom output.
* Tag articles Atom output.
*
*
* @param context the specified context
* @param context the specified context
* @throws IOException io exception
* @throws IOException io exception
*/
*/
@RequestProcessing
(
value
=
{
"/tag-articles-feed.do"
},
method
=
{
HTTPRequestMethod
.
GET
,
HTTPRequestMethod
.
HEAD
})
@RequestProcessing
(
value
=
{
"/tag-articles-feed.do"
},
method
=
{
HTTPRequestMethod
.
GET
,
HTTPRequestMethod
.
HEAD
})
public
void
tagArticlesAtom
(
final
HTTPRequestContext
context
)
throws
IOException
{
public
void
tagArticlesAtom
(
final
HTTPRequestContext
context
)
throws
IOException
{
final
AtomRenderer
renderer
=
new
AtomRenderer
();
final
AtomRenderer
renderer
=
new
AtomRenderer
();
context
.
setRenderer
(
renderer
);
context
.
setRenderer
(
renderer
);
final
HttpServletRequest
request
=
context
.
getRequest
();
final
HttpServletRequest
request
=
context
.
getRequest
();
final
HttpServletResponse
response
=
context
.
getResponse
();
final
HttpServletResponse
response
=
context
.
getResponse
();
final
String
queryString
=
request
.
getQueryString
();
final
String
queryString
=
request
.
getQueryString
();
if
(
Strings
.
isEmptyOrNull
(
queryString
))
{
if
(
Strings
.
isEmptyOrNull
(
queryString
))
{
response
.
sendError
(
HttpServletResponse
.
SC_BAD_REQUEST
);
response
.
sendError
(
HttpServletResponse
.
SC_BAD_REQUEST
);
return
;
return
;
}
}
final
String
oIdMap
=
queryString
.
split
(
"&"
)[
0
];
final
String
oIdMap
=
queryString
.
split
(
"&"
)[
0
];
final
String
tagId
=
oIdMap
.
split
(
"="
)[
1
];
final
String
tagId
=
oIdMap
.
split
(
"="
)[
1
];
final
Feed
feed
=
new
Feed
();
final
Feed
feed
=
new
Feed
();
try
{
try
{
final
String
tagTitle
=
tagRepository
.
get
(
tagId
).
getString
(
Tag
.
TAG_TITLE
);
final
String
tagTitle
=
tagRepository
.
get
(
tagId
).
getString
(
Tag
.
TAG_TITLE
);
final
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
final
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
if
(
null
==
preference
)
{
if
(
null
==
preference
)
{
response
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
);
response
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
);
return
;
return
;
}
}
final
String
blogTitle
=
preference
.
getString
(
Preference
.
BLOG_TITLE
);
final
String
blogTitle
=
preference
.
getString
(
Preference
.
BLOG_TITLE
);
final
String
blogSubtitle
=
preference
.
getString
(
Preference
.
BLOG_SUBTITLE
)
+
", "
+
tagTitle
;
final
String
blogSubtitle
=
preference
.
getString
(
Preference
.
BLOG_SUBTITLE
)
+
", "
+
tagTitle
;
final
String
blogHost
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
String
blogHost
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
feed
.
setTitle
(
StringEscapeUtils
.
escapeXml
(
blogTitle
));
feed
.
setTitle
(
StringEscapeUtils
.
escapeXml
(
blogTitle
));
feed
.
setSubtitle
(
StringEscapeUtils
.
escapeXml
(
blogSubtitle
));
feed
.
setSubtitle
(
StringEscapeUtils
.
escapeXml
(
blogSubtitle
));
feed
.
setUpdated
(
TimeZones
.
getTime
(
preference
.
getString
(
Preference
.
TIME_ZONE_ID
)));
feed
.
setUpdated
(
TimeZones
.
getTime
(
preference
.
getString
(
Preference
.
TIME_ZONE_ID
)));
feed
.
setAuthor
(
StringEscapeUtils
.
escapeXml
(
blogTitle
));
feed
.
setAuthor
(
StringEscapeUtils
.
escapeXml
(
blogTitle
));
feed
.
setLink
(
"http://"
+
blogHost
+
"/tag-articles-feed.do"
);
feed
.
setLink
(
"http://"
+
blogHost
+
"/tag-articles-feed.do"
);
feed
.
setId
(
"http://"
+
blogHost
+
"/"
);
feed
.
setId
(
"http://"
+
blogHost
+
"/"
);
final
JSONObject
tagArticleResult
=
tagArticleRepository
.
getByTagId
(
tagId
,
1
,
ENTRY_OUTPUT_CNT
);
final
JSONObject
tagArticleResult
=
tagArticleRepository
.
getByTagId
(
tagId
,
1
,
ENTRY_OUTPUT_CNT
);
final
JSONArray
tagArticleRelations
=
tagArticleResult
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
tagArticleRelations
=
tagArticleResult
.
getJSONArray
(
Keys
.
RESULTS
);
if
(
0
==
tagArticleRelations
.
length
())
{
if
(
0
==
tagArticleRelations
.
length
())
{
response
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
);
response
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
);
return
;
return
;
}
}
final
List
<
JSONObject
>
articles
=
new
ArrayList
<
JSONObject
>();
final
List
<
JSONObject
>
articles
=
new
ArrayList
<
JSONObject
>();
for
(
int
i
=
0
;
i
<
tagArticleRelations
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
tagArticleRelations
.
length
();
i
++)
{
final
JSONObject
tagArticleRelation
=
tagArticleRelations
.
getJSONObject
(
i
);
final
JSONObject
tagArticleRelation
=
tagArticleRelations
.
getJSONObject
(
i
);
final
String
articleId
=
tagArticleRelation
.
getString
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
);
final
String
articleId
=
tagArticleRelation
.
getString
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
);
final
JSONObject
article
=
articleRepository
.
get
(
articleId
);
final
JSONObject
article
=
articleRepository
.
get
(
articleId
);
if
(
article
.
getBoolean
(
Article
.
ARTICLE_IS_PUBLISHED
))
{
// Skips the unpublished article
if
(
article
.
getBoolean
(
Article
.
ARTICLE_IS_PUBLISHED
))
{
// Skips the unpublished article
articles
.
add
(
article
);
articles
.
add
(
article
);
}
}
}
}
final
boolean
hasMultipleUsers
=
Users
.
getInstance
().
hasMultipleUsers
();
final
boolean
hasMultipleUsers
=
Users
.
getInstance
().
hasMultipleUsers
();
String
authorName
=
""
;
String
authorName
=
""
;
if
(!
hasMultipleUsers
&&
!
articles
.
isEmpty
())
{
if
(!
hasMultipleUsers
&&
!
articles
.
isEmpty
())
{
authorName
=
articleUtils
.
getAuthor
(
articles
.
get
(
0
)).
getString
(
User
.
USER_NAME
);
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
++)
{
for
(
int
i
=
0
;
i
<
articles
.
size
();
i
++)
{
final
JSONObject
article
=
articles
.
get
(
i
);
final
JSONObject
article
=
articles
.
get
(
i
);
final
Entry
entry
=
new
Entry
();
final
Entry
entry
=
new
Entry
();
feed
.
addEntry
(
entry
);
feed
.
addEntry
(
entry
);
final
String
title
=
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_TITLE
));
final
String
title
=
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_TITLE
));
entry
.
setTitle
(
title
);
entry
.
setTitle
(
title
);
final
String
summary
=
isFullContent
?
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_CONTENT
))
final
String
summary
=
isFullContent
?
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_CONTENT
))
:
StringEscapeUtils
.
escapeXml
(
article
.
optString
(
Article
.
ARTICLE_ABSTRACT
));
:
StringEscapeUtils
.
escapeXml
(
article
.
optString
(
Article
.
ARTICLE_ABSTRACT
));
entry
.
setSummary
(
summary
);
entry
.
setSummary
(
summary
);
final
Date
updated
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_UPDATE_DATE
);
final
Date
updated
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_UPDATE_DATE
);
entry
.
setUpdated
(
updated
);
entry
.
setUpdated
(
updated
);
final
String
link
=
"http://"
+
blogHost
+
article
.
getString
(
Article
.
ARTICLE_PERMALINK
);
final
String
link
=
"http://"
+
blogHost
+
article
.
getString
(
Article
.
ARTICLE_PERMALINK
);
entry
.
setLink
(
link
);
entry
.
setLink
(
link
);
entry
.
setId
(
link
);
entry
.
setId
(
link
);
if
(
hasMultipleUsers
)
{
if
(
hasMultipleUsers
)
{
authorName
=
StringEscapeUtils
.
escapeXml
(
articleUtils
.
getAuthor
(
article
).
getString
(
User
.
USER_NAME
));
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
tagsString
=
article
.
getString
(
Article
.
ARTICLE_TAGS_REF
);
final
String
[]
tagStrings
=
tagsString
.
split
(
","
);
final
String
[]
tagStrings
=
tagsString
.
split
(
","
);
for
(
int
j
=
0
;
j
<
tagStrings
.
length
;
j
++)
{
for
(
int
j
=
0
;
j
<
tagStrings
.
length
;
j
++)
{
final
Category
catetory
=
new
Category
();
final
Category
catetory
=
new
Category
();
entry
.
addCatetory
(
catetory
);
entry
.
addCatetory
(
catetory
);
final
String
tag
=
tagStrings
[
j
];
final
String
tag
=
tagStrings
[
j
];
catetory
.
setTerm
(
tag
);
catetory
.
setTerm
(
tag
);
}
}
}
}
renderer
.
setContent
(
feed
.
toString
());
renderer
.
setContent
(
feed
.
toString
());
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Get tag article feed error"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Get tag article feed error"
,
e
);
try
{
try
{
context
.
getResponse
().
sendError
(
HttpServletResponse
.
SC_SERVICE_UNAVAILABLE
);
context
.
getResponse
().
sendError
(
HttpServletResponse
.
SC_SERVICE_UNAVAILABLE
);
}
catch
(
final
IOException
ex
)
{
}
catch
(
final
IOException
ex
)
{
throw
new
RuntimeException
(
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
})
@RequestProcessing
(
value
=
{
"/blog-articles-rss.do"
},
method
=
{
HTTPRequestMethod
.
GET
,
HTTPRequestMethod
.
HEAD
})
public
void
blogArticlesRSS
(
final
HTTPRequestContext
context
)
{
public
void
blogArticlesRSS
(
final
HTTPRequestContext
context
)
{
final
HttpServletResponse
response
=
context
.
getResponse
();
final
HttpServletResponse
response
=
context
.
getResponse
();
final
RssRenderer
renderer
=
new
RssRenderer
();
final
RssRenderer
renderer
=
new
RssRenderer
();
context
.
setRenderer
(
renderer
);
context
.
setRenderer
(
renderer
);
final
Channel
channel
=
new
Channel
();
final
Channel
channel
=
new
Channel
();
try
{
try
{
final
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
final
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
if
(
null
==
preference
)
{
if
(
null
==
preference
)
{
response
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
);
response
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
);
return
;
return
;
}
}
final
String
blogTitle
=
preference
.
getString
(
Preference
.
BLOG_TITLE
);
final
String
blogTitle
=
preference
.
getString
(
Preference
.
BLOG_TITLE
);
final
String
blogSubtitle
=
preference
.
getString
(
Preference
.
BLOG_SUBTITLE
);
final
String
blogSubtitle
=
preference
.
getString
(
Preference
.
BLOG_SUBTITLE
);
final
String
blogHost
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
String
blogHost
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
channel
.
setTitle
(
StringEscapeUtils
.
escapeXml
(
blogTitle
));
channel
.
setTitle
(
StringEscapeUtils
.
escapeXml
(
blogTitle
));
channel
.
setLastBuildDate
(
TimeZones
.
getTime
(
preference
.
getString
(
Preference
.
TIME_ZONE_ID
)));
channel
.
setLastBuildDate
(
TimeZones
.
getTime
(
preference
.
getString
(
Preference
.
TIME_ZONE_ID
)));
channel
.
setLink
(
"http://"
+
blogHost
);
channel
.
setLink
(
"http://"
+
blogHost
);
channel
.
setAtomLink
(
"http://"
+
blogHost
+
"/blog-articles-rss.do"
);
channel
.
setAtomLink
(
"http://"
+
blogHost
+
"/blog-articles-rss.do"
);
channel
.
setGenerator
(
"B3log Solo, ver "
+
SoloServletListener
.
VERSION
);
channel
.
setGenerator
(
"B3log Solo, ver "
+
SoloServletListener
.
VERSION
);
final
String
localeString
=
preference
.
getString
(
Preference
.
LOCALE_STRING
);
final
String
localeString
=
preference
.
getString
(
Preference
.
LOCALE_STRING
);
final
String
country
=
Locales
.
getCountry
(
localeString
).
toLowerCase
();
final
String
country
=
Locales
.
getCountry
(
localeString
).
toLowerCase
();
final
String
language
=
Locales
.
getLanguage
(
localeString
).
toLowerCase
();
final
String
language
=
Locales
.
getLanguage
(
localeString
).
toLowerCase
();
channel
.
setLanguage
(
language
+
'-'
+
country
);
channel
.
setLanguage
(
language
+
'-'
+
country
);
channel
.
setDescription
(
blogSubtitle
);
channel
.
setDescription
(
blogSubtitle
);
final
Query
query
=
new
Query
().
setCurrentPageNum
(
1
).
final
Query
query
=
new
Query
().
setCurrentPageNum
(
1
).
setPageSize
(
ENTRY_OUTPUT_CNT
).
setPageSize
(
ENTRY_OUTPUT_CNT
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
).
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
).
setPageCount
(
1
);
setPageCount
(
1
);
final
JSONObject
articleResult
=
articleRepository
.
get
(
query
);
final
JSONObject
articleResult
=
articleRepository
.
get
(
query
);
final
JSONArray
articles
=
articleResult
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
articles
=
articleResult
.
getJSONArray
(
Keys
.
RESULTS
);
final
boolean
hasMultipleUsers
=
Users
.
getInstance
().
hasMultipleUsers
();
final
boolean
hasMultipleUsers
=
Users
.
getInstance
().
hasMultipleUsers
();
String
authorName
=
""
;
String
authorName
=
""
;
if
(!
hasMultipleUsers
&&
0
!=
articles
.
length
())
{
if
(!
hasMultipleUsers
&&
0
!=
articles
.
length
())
{
authorName
=
articleUtils
.
getAuthor
(
articles
.
getJSONObject
(
0
)).
getString
(
User
.
USER_NAME
);
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
++)
{
for
(
int
i
=
0
;
i
<
articles
.
length
();
i
++)
{
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
final
Item
item
=
new
Item
();
final
Item
item
=
new
Item
();
channel
.
addItem
(
item
);
channel
.
addItem
(
item
);
final
String
title
=
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_TITLE
));
final
String
title
=
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_TITLE
));
item
.
setTitle
(
title
);
item
.
setTitle
(
title
);
final
String
description
=
isFullContent
?
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_CONTENT
))
final
String
description
=
isFullContent
?
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_CONTENT
))
:
StringEscapeUtils
.
escapeXml
(
article
.
optString
(
Article
.
ARTICLE_ABSTRACT
));
:
StringEscapeUtils
.
escapeXml
(
article
.
optString
(
Article
.
ARTICLE_ABSTRACT
));
item
.
setDescription
(
description
);
item
.
setDescription
(
description
);
final
Date
pubDate
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_UPDATE_DATE
);
final
Date
pubDate
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_UPDATE_DATE
);
item
.
setPubDate
(
pubDate
);
item
.
setPubDate
(
pubDate
);
final
String
link
=
"http://"
+
blogHost
+
article
.
getString
(
Article
.
ARTICLE_PERMALINK
);
final
String
link
=
"http://"
+
blogHost
+
article
.
getString
(
Article
.
ARTICLE_PERMALINK
);
item
.
setLink
(
link
);
item
.
setLink
(
link
);
item
.
setGUID
(
link
);
item
.
setGUID
(
link
);
final
String
authorEmail
=
article
.
getString
(
Article
.
ARTICLE_AUTHOR_EMAIL
);
final
String
authorEmail
=
article
.
getString
(
Article
.
ARTICLE_AUTHOR_EMAIL
);
if
(
hasMultipleUsers
)
{
if
(
hasMultipleUsers
)
{
authorName
=
StringEscapeUtils
.
escapeXml
(
articleUtils
.
getAuthor
(
article
).
getString
(
User
.
USER_NAME
));
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
tagsString
=
article
.
getString
(
Article
.
ARTICLE_TAGS_REF
);
final
String
[]
tagStrings
=
tagsString
.
split
(
","
);
final
String
[]
tagStrings
=
tagsString
.
split
(
","
);
for
(
int
j
=
0
;
j
<
tagStrings
.
length
;
j
++)
{
for
(
int
j
=
0
;
j
<
tagStrings
.
length
;
j
++)
{
final
org
.
b3log
.
solo
.
model
.
feed
.
rss
.
Category
catetory
=
new
org
.
b3log
.
solo
.
model
.
feed
.
rss
.
Category
();
final
org
.
b3log
.
solo
.
model
.
feed
.
rss
.
Category
catetory
=
new
org
.
b3log
.
solo
.
model
.
feed
.
rss
.
Category
();
item
.
addCatetory
(
catetory
);
item
.
addCatetory
(
catetory
);
final
String
tag
=
tagStrings
[
j
];
final
String
tag
=
tagStrings
[
j
];
catetory
.
setTerm
(
tag
);
catetory
.
setTerm
(
tag
);
}
}
}
}
renderer
.
setContent
(
channel
.
toString
());
renderer
.
setContent
(
channel
.
toString
());
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Get blog article rss error"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Get blog article rss error"
,
e
);
try
{
try
{
context
.
getResponse
().
sendError
(
HttpServletResponse
.
SC_SERVICE_UNAVAILABLE
);
context
.
getResponse
().
sendError
(
HttpServletResponse
.
SC_SERVICE_UNAVAILABLE
);
}
catch
(
final
IOException
ex
)
{
}
catch
(
final
IOException
ex
)
{
throw
new
RuntimeException
(
ex
);
throw
new
RuntimeException
(
ex
);
}
}
}
}
}
}
/**
/**
* Tag articles RSS output.
* Tag articles RSS output.
*
*
* @param context the specified context
* @param context the specified context
* @throws IOException io exception
* @throws IOException io exception
*/
*/
@RequestProcessing
(
value
=
{
"/tag-articles-rss.do"
},
method
=
{
HTTPRequestMethod
.
GET
,
HTTPRequestMethod
.
HEAD
})
@RequestProcessing
(
value
=
{
"/tag-articles-rss.do"
},
method
=
{
HTTPRequestMethod
.
GET
,
HTTPRequestMethod
.
HEAD
})
public
void
tagArticlesRSS
(
final
HTTPRequestContext
context
)
throws
IOException
{
public
void
tagArticlesRSS
(
final
HTTPRequestContext
context
)
throws
IOException
{
final
HttpServletResponse
response
=
context
.
getResponse
();
final
HttpServletResponse
response
=
context
.
getResponse
();
final
HttpServletRequest
request
=
context
.
getRequest
();
final
HttpServletRequest
request
=
context
.
getRequest
();
final
RssRenderer
renderer
=
new
RssRenderer
();
final
RssRenderer
renderer
=
new
RssRenderer
();
context
.
setRenderer
(
renderer
);
context
.
setRenderer
(
renderer
);
final
String
queryString
=
request
.
getQueryString
();
final
String
queryString
=
request
.
getQueryString
();
if
(
Strings
.
isEmptyOrNull
(
queryString
))
{
if
(
Strings
.
isEmptyOrNull
(
queryString
))
{
response
.
sendError
(
HttpServletResponse
.
SC_BAD_REQUEST
);
response
.
sendError
(
HttpServletResponse
.
SC_BAD_REQUEST
);
return
;
return
;
}
}
final
String
oIdMap
=
queryString
.
split
(
"&"
)[
0
];
final
String
oIdMap
=
queryString
.
split
(
"&"
)[
0
];
final
String
tagId
=
oIdMap
.
split
(
"="
)[
1
];
final
String
tagId
=
oIdMap
.
split
(
"="
)[
1
];
final
Channel
channel
=
new
Channel
();
final
Channel
channel
=
new
Channel
();
try
{
try
{
final
String
tagTitle
=
tagRepository
.
get
(
tagId
).
getString
(
Tag
.
TAG_TITLE
);
final
String
tagTitle
=
tagRepository
.
get
(
tagId
).
getString
(
Tag
.
TAG_TITLE
);
final
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
final
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
if
(
null
==
preference
)
{
if
(
null
==
preference
)
{
response
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
);
response
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
);
return
;
return
;
}
}
final
String
blogTitle
=
preference
.
getString
(
Preference
.
BLOG_TITLE
);
final
String
blogTitle
=
preference
.
getString
(
Preference
.
BLOG_TITLE
);
final
String
blogSubtitle
=
preference
.
getString
(
Preference
.
BLOG_SUBTITLE
)
+
", "
+
tagTitle
;
final
String
blogSubtitle
=
preference
.
getString
(
Preference
.
BLOG_SUBTITLE
)
+
", "
+
tagTitle
;
final
String
blogHost
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
String
blogHost
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
channel
.
setTitle
(
StringEscapeUtils
.
escapeXml
(
blogTitle
));
channel
.
setTitle
(
StringEscapeUtils
.
escapeXml
(
blogTitle
));
channel
.
setLastBuildDate
(
TimeZones
.
getTime
(
preference
.
getString
(
Preference
.
TIME_ZONE_ID
)));
channel
.
setLastBuildDate
(
TimeZones
.
getTime
(
preference
.
getString
(
Preference
.
TIME_ZONE_ID
)));
channel
.
setLink
(
"http://"
+
blogHost
);
channel
.
setLink
(
"http://"
+
blogHost
);
channel
.
setAtomLink
(
"http://"
+
blogHost
+
"/tag-articles-rss.do"
);
channel
.
setAtomLink
(
"http://"
+
blogHost
+
"/tag-articles-rss.do"
);
channel
.
setGenerator
(
"B3log Solo, ver "
+
SoloServletListener
.
VERSION
);
channel
.
setGenerator
(
"B3log Solo, ver "
+
SoloServletListener
.
VERSION
);
final
String
localeString
=
preference
.
getString
(
Preference
.
LOCALE_STRING
);
final
String
localeString
=
preference
.
getString
(
Preference
.
LOCALE_STRING
);
final
String
country
=
Locales
.
getCountry
(
localeString
).
toLowerCase
();
final
String
country
=
Locales
.
getCountry
(
localeString
).
toLowerCase
();
final
String
language
=
Locales
.
getLanguage
(
localeString
).
toLowerCase
();
final
String
language
=
Locales
.
getLanguage
(
localeString
).
toLowerCase
();
channel
.
setLanguage
(
language
+
'-'
+
country
);
channel
.
setLanguage
(
language
+
'-'
+
country
);
channel
.
setDescription
(
blogSubtitle
);
channel
.
setDescription
(
blogSubtitle
);
final
JSONObject
tagArticleResult
=
tagArticleRepository
.
getByTagId
(
tagId
,
1
,
ENTRY_OUTPUT_CNT
);
final
JSONObject
tagArticleResult
=
tagArticleRepository
.
getByTagId
(
tagId
,
1
,
ENTRY_OUTPUT_CNT
);
final
JSONArray
tagArticleRelations
=
tagArticleResult
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
tagArticleRelations
=
tagArticleResult
.
getJSONArray
(
Keys
.
RESULTS
);
if
(
0
==
tagArticleRelations
.
length
())
{
if
(
0
==
tagArticleRelations
.
length
())
{
response
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
);
response
.
sendError
(
HttpServletResponse
.
SC_NOT_FOUND
);
return
;
return
;
}
}
final
List
<
JSONObject
>
articles
=
new
ArrayList
<
JSONObject
>();
final
List
<
JSONObject
>
articles
=
new
ArrayList
<
JSONObject
>();
for
(
int
i
=
0
;
i
<
tagArticleRelations
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
tagArticleRelations
.
length
();
i
++)
{
final
JSONObject
tagArticleRelation
=
tagArticleRelations
.
getJSONObject
(
i
);
final
JSONObject
tagArticleRelation
=
tagArticleRelations
.
getJSONObject
(
i
);
final
String
articleId
=
tagArticleRelation
.
getString
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
);
final
String
articleId
=
tagArticleRelation
.
getString
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
);
final
JSONObject
article
=
articleRepository
.
get
(
articleId
);
final
JSONObject
article
=
articleRepository
.
get
(
articleId
);
if
(
article
.
getBoolean
(
Article
.
ARTICLE_IS_PUBLISHED
))
{
// Skips the unpublished article
if
(
article
.
getBoolean
(
Article
.
ARTICLE_IS_PUBLISHED
))
{
// Skips the unpublished article
articles
.
add
(
article
);
articles
.
add
(
article
);
}
}
}
}
final
boolean
hasMultipleUsers
=
Users
.
getInstance
().
hasMultipleUsers
();
final
boolean
hasMultipleUsers
=
Users
.
getInstance
().
hasMultipleUsers
();
String
authorName
=
""
;
String
authorName
=
""
;
if
(!
hasMultipleUsers
&&
!
articles
.
isEmpty
())
{
if
(!
hasMultipleUsers
&&
!
articles
.
isEmpty
())
{
authorName
=
articleUtils
.
getAuthor
(
articles
.
get
(
0
)).
getString
(
User
.
USER_NAME
);
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
++)
{
for
(
int
i
=
0
;
i
<
articles
.
size
();
i
++)
{
final
JSONObject
article
=
articles
.
get
(
i
);
final
JSONObject
article
=
articles
.
get
(
i
);
final
Item
item
=
new
Item
();
final
Item
item
=
new
Item
();
channel
.
addItem
(
item
);
channel
.
addItem
(
item
);
final
String
title
=
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_TITLE
));
final
String
title
=
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_TITLE
));
item
.
setTitle
(
title
);
item
.
setTitle
(
title
);
final
String
description
=
isFullContent
?
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_CONTENT
))
final
String
description
=
isFullContent
?
StringEscapeUtils
.
escapeXml
(
article
.
getString
(
Article
.
ARTICLE_CONTENT
))
:
StringEscapeUtils
.
escapeXml
(
article
.
optString
(
Article
.
ARTICLE_ABSTRACT
));
:
StringEscapeUtils
.
escapeXml
(
article
.
optString
(
Article
.
ARTICLE_ABSTRACT
));
item
.
setDescription
(
description
);
item
.
setDescription
(
description
);
final
Date
pubDate
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_UPDATE_DATE
);
final
Date
pubDate
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_UPDATE_DATE
);
item
.
setPubDate
(
pubDate
);
item
.
setPubDate
(
pubDate
);
final
String
link
=
"http://"
+
blogHost
+
article
.
getString
(
Article
.
ARTICLE_PERMALINK
);
final
String
link
=
"http://"
+
blogHost
+
article
.
getString
(
Article
.
ARTICLE_PERMALINK
);
item
.
setLink
(
link
);
item
.
setLink
(
link
);
item
.
setGUID
(
link
);
item
.
setGUID
(
link
);
final
String
authorEmail
=
article
.
getString
(
Article
.
ARTICLE_AUTHOR_EMAIL
);
final
String
authorEmail
=
article
.
getString
(
Article
.
ARTICLE_AUTHOR_EMAIL
);
if
(
hasMultipleUsers
)
{
if
(
hasMultipleUsers
)
{
authorName
=
StringEscapeUtils
.
escapeXml
(
articleUtils
.
getAuthor
(
article
).
getString
(
User
.
USER_NAME
));
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
tagsString
=
article
.
getString
(
Article
.
ARTICLE_TAGS_REF
);
final
String
[]
tagStrings
=
tagsString
.
split
(
","
);
final
String
[]
tagStrings
=
tagsString
.
split
(
","
);
for
(
int
j
=
0
;
j
<
tagStrings
.
length
;
j
++)
{
for
(
int
j
=
0
;
j
<
tagStrings
.
length
;
j
++)
{
final
org
.
b3log
.
solo
.
model
.
feed
.
rss
.
Category
catetory
=
new
org
.
b3log
.
solo
.
model
.
feed
.
rss
.
Category
();
final
org
.
b3log
.
solo
.
model
.
feed
.
rss
.
Category
catetory
=
new
org
.
b3log
.
solo
.
model
.
feed
.
rss
.
Category
();
item
.
addCatetory
(
catetory
);
item
.
addCatetory
(
catetory
);
final
String
tag
=
tagStrings
[
j
];
final
String
tag
=
tagStrings
[
j
];
catetory
.
setTerm
(
tag
);
catetory
.
setTerm
(
tag
);
}
}
}
}
renderer
.
setContent
(
channel
.
toString
());
renderer
.
setContent
(
channel
.
toString
());
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Get tag article rss error"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Get tag article rss error"
,
e
);
try
{
try
{
context
.
getResponse
().
sendError
(
HttpServletResponse
.
SC_SERVICE_UNAVAILABLE
);
context
.
getResponse
().
sendError
(
HttpServletResponse
.
SC_SERVICE_UNAVAILABLE
);
}
catch
(
final
IOException
ex
)
{
}
catch
(
final
IOException
ex
)
{
throw
new
RuntimeException
(
ex
);
throw
new
RuntimeException
(
ex
);
}
}
}
}
}
}
}
}
core/src/main/java/org/b3log/solo/processor/SitemapProcessor.java
View file @
65f8a5e9
/*
/*
* 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.Query
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.servlet.HTTPRequestContext
;
import
org.b3log.latke.servlet.HTTPRequestContext
;
import
org.b3log.latke.servlet.HTTPRequestMethod
;
import
org.b3log.latke.servlet.HTTPRequestMethod
;
import
org.b3log.latke.servlet.renderer.TextXMLRenderer
;
import
org.b3log.latke.servlet.renderer.TextXMLRenderer
;
import
org.b3log.solo.model.ArchiveDate
;
import
org.b3log.solo.model.ArchiveDate
;
import
org.b3log.solo.model.Article
;
import
org.b3log.solo.model.Article
;
import
org.b3log.solo.model.Page
;
import
org.b3log.solo.model.Page
;
import
org.b3log.solo.model.Preference
;
import
org.b3log.solo.model.Preference
;
import
org.b3log.solo.model.Tag
;
import
org.b3log.solo.model.Tag
;
import
org.b3log.solo.model.sitemap.Sitemap
;
import
org.b3log.solo.model.sitemap.Sitemap
;
import
org.b3log.solo.model.sitemap.URL
;
import
org.b3log.solo.model.sitemap.URL
;
import
org.b3log.solo.repository.ArchiveDateRepository
;
import
org.b3log.solo.repository.ArchiveDateRepository
;
import
org.b3log.solo.repository.PageRepository
;
import
org.b3log.solo.repository.PageRepository
;
import
org.b3log.solo.repository.TagRepository
;
import
org.b3log.solo.repository.TagRepository
;
import
org.b3log.solo.repository.impl.ArchiveDateRepositoryImpl
;
import
org.b3log.solo.repository.impl.ArchiveDateRepositoryImpl
;
import
org.b3log.solo.repository.impl.ArticleRepositoryImpl
;
import
org.b3log.solo.repository.impl.ArticleRepositoryImpl
;
import
org.b3log.solo.repository.impl.PageRepositoryImpl
;
import
org.b3log.solo.repository.impl.PageRepositoryImpl
;
import
org.b3log.solo.repository.impl.TagRepositoryImpl
;
import
org.b3log.solo.repository.impl.TagRepositoryImpl
;
import
org.b3log.solo.service.PreferenceQueryService
;
import
org.b3log.solo.service.PreferenceQueryService
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
/**
/**
* Site map (sitemap) processor.
* Site map (sitemap) processor.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.4, Jun 11, 2012
* @version 1.0.0.4, Jun 11, 2012
* @since 0.3.1
* @since 0.3.1
*/
*/
@RequestProcessor
@RequestProcessor
public
final
class
SitemapProcessor
{
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
)
@RequestProcessing
(
value
=
{
"/sitemap.xml"
},
method
=
HTTPRequestMethod
.
GET
)
public
void
sitemap
(
final
HTTPRequestContext
context
)
{
public
void
sitemap
(
final
HTTPRequestContext
context
)
{
final
TextXMLRenderer
renderer
=
new
TextXMLRenderer
();
final
TextXMLRenderer
renderer
=
new
TextXMLRenderer
();
context
.
setRenderer
(
renderer
);
context
.
setRenderer
(
renderer
);
final
Sitemap
sitemap
=
new
Sitemap
();
final
Sitemap
sitemap
=
new
Sitemap
();
try
{
try
{
final
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
final
JSONObject
preference
=
preferenceQueryService
.
getPreference
();
addArticles
(
sitemap
,
preference
);
addArticles
(
sitemap
,
preference
);
addNavigations
(
sitemap
,
preference
);
addNavigations
(
sitemap
,
preference
);
addTags
(
sitemap
,
preference
);
addTags
(
sitemap
,
preference
);
addArchives
(
sitemap
,
preference
);
addArchives
(
sitemap
,
preference
);
LOGGER
.
log
(
Level
.
INFO
,
"Generating sitemap...."
);
LOGGER
.
log
(
Level
.
INFO
,
"Generating sitemap...."
);
final
String
content
=
sitemap
.
toString
();
final
String
content
=
sitemap
.
toString
();
LOGGER
.
log
(
Level
.
INFO
,
"Generated sitemap"
);
LOGGER
.
log
(
Level
.
INFO
,
"Generated sitemap"
);
renderer
.
setContent
(
content
);
renderer
.
setContent
(
content
);
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Get blog article feed error"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Get blog article feed error"
,
e
);
try
{
try
{
context
.
getResponse
().
sendError
(
HttpServletResponse
.
SC_SERVICE_UNAVAILABLE
);
context
.
getResponse
().
sendError
(
HttpServletResponse
.
SC_SERVICE_UNAVAILABLE
);
}
catch
(
final
IOException
ex
)
{
}
catch
(
final
IOException
ex
)
{
throw
new
RuntimeException
(
ex
);
throw
new
RuntimeException
(
ex
);
}
}
}
}
}
}
/**
/**
* Adds articles into the specified sitemap.
* Adds articles into the specified sitemap.
*
*
* @param sitemap the specified sitemap
* @param sitemap the specified sitemap
* @param preference the specified preference
* @param preference the specified preference
* @throws Exception exception
* @throws Exception exception
*/
*/
private
void
addArticles
(
final
Sitemap
sitemap
,
final
JSONObject
preference
)
throws
Exception
{
private
void
addArticles
(
final
Sitemap
sitemap
,
final
JSONObject
preference
)
throws
Exception
{
final
String
host
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
String
host
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
// XXX: query all articles?
// XXX: query all articles?
final
Query
query
=
new
Query
().
setCurrentPageNum
(
1
).
final
Query
query
=
new
Query
().
setCurrentPageNum
(
1
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addSort
(
Article
.
ARTICLE_CREATE_DATE
,
SortDirection
.
DESCENDING
);
addSort
(
Article
.
ARTICLE_CREATE_DATE
,
SortDirection
.
DESCENDING
);
// Closes cache avoid Java heap space out of memory while caching
// Closes cache avoid Java heap space out of memory while caching
// query results
// query results
articleRepository
.
setCacheEnabled
(
false
);
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
);
final
JSONArray
articles
=
articleResult
.
getJSONArray
(
Keys
.
RESULTS
);
for
(
int
i
=
0
;
i
<
articles
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
articles
.
length
();
i
++)
{
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
final
String
permalink
=
article
.
getString
(
Article
.
ARTICLE_PERMALINK
);
final
String
permalink
=
article
.
getString
(
Article
.
ARTICLE_PERMALINK
);
final
URL
url
=
new
URL
();
final
URL
url
=
new
URL
();
url
.
setLoc
(
"http://"
+
host
+
permalink
);
url
.
setLoc
(
"http://"
+
host
+
permalink
);
final
Date
updateDate
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_UPDATE_DATE
);
final
Date
updateDate
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_UPDATE_DATE
);
final
String
lastMod
=
DateFormatUtils
.
ISO_DATETIME_TIME_ZONE_FORMAT
.
format
(
updateDate
);
final
String
lastMod
=
DateFormatUtils
.
ISO_DATETIME_TIME_ZONE_FORMAT
.
format
(
updateDate
);
url
.
setLastMod
(
lastMod
);
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 sitemap the specified sitemap
* @param preference the specified preference
* @param preference the specified preference
* @throws Exception exception
* @throws Exception exception
*/
*/
private
void
addNavigations
(
final
Sitemap
sitemap
,
final
JSONObject
preference
)
throws
Exception
{
private
void
addNavigations
(
final
Sitemap
sitemap
,
final
JSONObject
preference
)
throws
Exception
{
final
String
host
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
String
host
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
JSONObject
result
=
pageRepository
.
get
(
new
Query
());
final
JSONObject
result
=
pageRepository
.
get
(
new
Query
());
final
JSONArray
pages
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
pages
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
for
(
int
i
=
0
;
i
<
pages
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
pages
.
length
();
i
++)
{
final
JSONObject
page
=
pages
.
getJSONObject
(
i
);
final
JSONObject
page
=
pages
.
getJSONObject
(
i
);
final
String
permalink
=
page
.
getString
(
Page
.
PAGE_PERMALINK
);
final
String
permalink
=
page
.
getString
(
Page
.
PAGE_PERMALINK
);
final
URL
url
=
new
URL
();
final
URL
url
=
new
URL
();
// The navigation maybe a page or a link
// The navigation maybe a page or a link
// Just filters for user mistakes tolerance
// Just filters for user mistakes tolerance
if
(!
permalink
.
contains
(
"://"
))
{
if
(!
permalink
.
contains
(
"://"
))
{
url
.
setLoc
(
"http://"
+
host
+
permalink
);
url
.
setLoc
(
"http://"
+
host
+
permalink
);
}
else
{
}
else
{
url
.
setLoc
(
permalink
);
url
.
setLoc
(
permalink
);
}
}
sitemap
.
addURL
(
url
);
sitemap
.
addURL
(
url
);
}
}
}
}
/**
/**
* Adds tags (tag-articles) and tags wall (/tags.html) into the specified
* Adds tags (tag-articles) and tags wall (/tags.html) into the specified
* sitemap.
* sitemap.
*
*
* @param sitemap the specified sitemap
* @param sitemap the specified sitemap
* @param preference the specified preference
* @param preference the specified preference
* @throws Exception exception
* @throws Exception exception
*/
*/
private
void
addTags
(
final
Sitemap
sitemap
,
final
JSONObject
preference
)
throws
Exception
{
private
void
addTags
(
final
Sitemap
sitemap
,
final
JSONObject
preference
)
throws
Exception
{
final
String
host
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
String
host
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
JSONObject
result
=
tagRepository
.
get
(
new
Query
());
final
JSONObject
result
=
tagRepository
.
get
(
new
Query
());
final
JSONArray
tags
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
tags
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
for
(
int
i
=
0
;
i
<
tags
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
tags
.
length
();
i
++)
{
final
JSONObject
tag
=
tags
.
getJSONObject
(
i
);
final
JSONObject
tag
=
tags
.
getJSONObject
(
i
);
final
String
link
=
URLEncoder
.
encode
(
tag
.
getString
(
Tag
.
TAG_TITLE
),
"UTF-8"
);
final
String
link
=
URLEncoder
.
encode
(
tag
.
getString
(
Tag
.
TAG_TITLE
),
"UTF-8"
);
final
URL
url
=
new
URL
();
final
URL
url
=
new
URL
();
url
.
setLoc
(
"http://"
+
host
+
"/tags/"
+
link
);
url
.
setLoc
(
"http://"
+
host
+
"/tags/"
+
link
);
sitemap
.
addURL
(
url
);
sitemap
.
addURL
(
url
);
}
}
// Tags wall
// Tags wall
final
URL
url
=
new
URL
();
final
URL
url
=
new
URL
();
url
.
setLoc
(
"http://"
+
host
+
"/tags.html"
);
url
.
setLoc
(
"http://"
+
host
+
"/tags.html"
);
sitemap
.
addURL
(
url
);
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 sitemap the specified sitemap
* @param preference the specified preference
* @param preference the specified preference
* @throws Exception exception
* @throws Exception exception
*/
*/
private
void
addArchives
(
final
Sitemap
sitemap
,
final
JSONObject
preference
)
throws
Exception
{
private
void
addArchives
(
final
Sitemap
sitemap
,
final
JSONObject
preference
)
throws
Exception
{
final
String
host
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
String
host
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
JSONObject
result
=
archiveDateRepository
.
get
(
new
Query
());
final
JSONObject
result
=
archiveDateRepository
.
get
(
new
Query
());
final
JSONArray
archiveDates
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
archiveDates
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
for
(
int
i
=
0
;
i
<
archiveDates
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
archiveDates
.
length
();
i
++)
{
final
JSONObject
archiveDate
=
archiveDates
.
getJSONObject
(
i
);
final
JSONObject
archiveDate
=
archiveDates
.
getJSONObject
(
i
);
final
long
time
=
archiveDate
.
getLong
(
ArchiveDate
.
ARCHIVE_TIME
);
final
long
time
=
archiveDate
.
getLong
(
ArchiveDate
.
ARCHIVE_TIME
);
final
String
dateString
=
ArchiveDate
.
DATE_FORMAT
.
format
(
time
);
final
String
dateString
=
ArchiveDate
.
DATE_FORMAT
.
format
(
time
);
final
URL
url
=
new
URL
();
final
URL
url
=
new
URL
();
url
.
setLoc
(
"http://"
+
host
+
"/archives/"
+
dateString
);
url
.
setLoc
(
"http://"
+
host
+
"/archives/"
+
dateString
);
sitemap
.
addURL
(
url
);
sitemap
.
addURL
(
url
);
}
}
}
}
}
}
core/src/main/java/org/b3log/solo/processor/util/Filler.java
View file @
65f8a5e9
/*
/*
* 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.FilterOperator
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.service.ServiceException
;
import
org.b3log.latke.service.ServiceException
;
import
org.b3log.latke.util.*
;
import
org.b3log.latke.util.*
;
import
org.b3log.latke.util.freemarker.Templates
;
import
org.b3log.latke.util.freemarker.Templates
;
import
org.b3log.solo.model.ArchiveDate
;
import
org.b3log.solo.model.ArchiveDate
;
import
org.b3log.solo.model.Link
;
import
org.b3log.solo.model.Link
;
import
org.b3log.solo.model.Preference
;
import
org.b3log.solo.model.Preference
;
import
org.b3log.solo.repository.CommentRepository
;
import
org.b3log.solo.repository.CommentRepository
;
import
org.b3log.solo.repository.LinkRepository
;
import
org.b3log.solo.repository.LinkRepository
;
import
org.b3log.solo.SoloServletListener
;
import
org.b3log.solo.SoloServletListener
;
import
org.b3log.solo.model.*
;
import
org.b3log.solo.model.*
;
import
org.b3log.solo.repository.ArchiveDateRepository
;
import
org.b3log.solo.repository.ArchiveDateRepository
;
import
org.b3log.solo.repository.PageRepository
;
import
org.b3log.solo.repository.PageRepository
;
import
org.b3log.solo.repository.StatisticRepository
;
import
org.b3log.solo.repository.StatisticRepository
;
import
org.b3log.solo.repository.UserRepository
;
import
org.b3log.solo.repository.UserRepository
;
import
org.b3log.solo.repository.impl.ArchiveDateRepositoryImpl
;
import
org.b3log.solo.repository.impl.ArchiveDateRepositoryImpl
;
import
org.b3log.solo.repository.impl.ArticleRepositoryImpl
;
import
org.b3log.solo.repository.impl.ArticleRepositoryImpl
;
import
org.b3log.solo.repository.impl.CommentRepositoryImpl
;
import
org.b3log.solo.repository.impl.CommentRepositoryImpl
;
import
org.b3log.solo.repository.impl.LinkRepositoryImpl
;
import
org.b3log.solo.repository.impl.LinkRepositoryImpl
;
import
org.b3log.solo.repository.impl.PageRepositoryImpl
;
import
org.b3log.solo.repository.impl.PageRepositoryImpl
;
import
org.b3log.solo.repository.impl.StatisticRepositoryImpl
;
import
org.b3log.solo.repository.impl.StatisticRepositoryImpl
;
import
org.b3log.solo.repository.impl.TagRepositoryImpl
;
import
org.b3log.solo.repository.impl.TagRepositoryImpl
;
import
org.b3log.solo.repository.impl.UserRepositoryImpl
;
import
org.b3log.solo.repository.impl.UserRepositoryImpl
;
import
org.b3log.solo.service.ArticleQueryService
;
import
org.b3log.solo.service.ArticleQueryService
;
import
org.b3log.solo.util.Tags
;
import
org.b3log.solo.util.Tags
;
import
org.b3log.solo.util.Users
;
import
org.b3log.solo.util.Users
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONException
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
/**
/**
* Filler utilities.
* Filler utilities.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.5.9, May 22, 2012
* @version 1.0.5.9, May 22, 2012
* @since 0.3.1
* @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 dataModel data model
* @param currentPageNum current page number
* @param currentPageNum current page number
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
void
fillIndexArticles
(
final
Map
<
String
,
Object
>
dataModel
,
final
int
currentPageNum
,
final
JSONObject
preference
)
public
void
fillIndexArticles
(
final
Map
<
String
,
Object
>
dataModel
,
final
int
currentPageNum
,
final
JSONObject
preference
)
throws
ServiceException
{
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Index Articles"
);
Stopwatchs
.
start
(
"Fill Index Articles"
);
try
{
try
{
final
int
pageSize
=
preference
.
getInt
(
Preference
.
ARTICLE_LIST_DISPLAY_COUNT
);
final
int
pageSize
=
preference
.
getInt
(
Preference
.
ARTICLE_LIST_DISPLAY_COUNT
);
final
int
windowSize
=
preference
.
getInt
(
Preference
.
ARTICLE_LIST_PAGINATION_WINDOW_SIZE
);
final
int
windowSize
=
preference
.
getInt
(
Preference
.
ARTICLE_LIST_PAGINATION_WINDOW_SIZE
);
final
JSONObject
statistic
=
statisticRepository
.
get
(
Statistic
.
STATISTIC
);
final
JSONObject
statistic
=
statisticRepository
.
get
(
Statistic
.
STATISTIC
);
final
int
publishedArticleCnt
=
statistic
.
getInt
(
Statistic
.
STATISTIC_PUBLISHED_ARTICLE_COUNT
);
final
int
publishedArticleCnt
=
statistic
.
getInt
(
Statistic
.
STATISTIC_PUBLISHED_ARTICLE_COUNT
);
final
int
pageCount
=
(
int
)
Math
.
ceil
((
double
)
publishedArticleCnt
/
(
double
)
pageSize
);
final
int
pageCount
=
(
int
)
Math
.
ceil
((
double
)
publishedArticleCnt
/
(
double
)
pageSize
);
final
Query
query
=
new
Query
().
setCurrentPageNum
(
currentPageNum
).
setPageSize
(
pageSize
).
setPageCount
(
pageCount
).
final
Query
query
=
new
Query
().
setCurrentPageNum
(
currentPageNum
).
setPageSize
(
pageSize
).
setPageCount
(
pageCount
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
PUBLISHED
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
PUBLISHED
).
addSort
(
Article
.
ARTICLE_PUT_TOP
,
SortDirection
.
DESCENDING
).
addSort
(
Article
.
ARTICLE_PUT_TOP
,
SortDirection
.
DESCENDING
).
index
(
Article
.
ARTICLE_PERMALINK
);
index
(
Article
.
ARTICLE_PERMALINK
);
if
(
preference
.
getBoolean
(
Preference
.
ENABLE_ARTICLE_UPDATE_HINT
))
{
if
(
preference
.
getBoolean
(
Preference
.
ENABLE_ARTICLE_UPDATE_HINT
))
{
query
.
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
);
query
.
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
);
}
else
{
}
else
{
query
.
addSort
(
Article
.
ARTICLE_CREATE_DATE
,
SortDirection
.
DESCENDING
);
query
.
addSort
(
Article
.
ARTICLE_CREATE_DATE
,
SortDirection
.
DESCENDING
);
}
}
final
JSONObject
result
=
articleRepository
.
get
(
query
);
final
JSONObject
result
=
articleRepository
.
get
(
query
);
final
List
<
Integer
>
pageNums
=
Paginator
.
paginate
(
currentPageNum
,
pageSize
,
pageCount
,
windowSize
);
final
List
<
Integer
>
pageNums
=
Paginator
.
paginate
(
currentPageNum
,
pageSize
,
pageCount
,
windowSize
);
if
(
0
!=
pageNums
.
size
())
{
if
(
0
!=
pageNums
.
size
())
{
dataModel
.
put
(
Pagination
.
PAGINATION_FIRST_PAGE_NUM
,
pageNums
.
get
(
0
));
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_LAST_PAGE_NUM
,
pageNums
.
get
(
pageNums
.
size
()
-
1
));
}
}
dataModel
.
put
(
Pagination
.
PAGINATION_PAGE_COUNT
,
pageCount
);
dataModel
.
put
(
Pagination
.
PAGINATION_PAGE_COUNT
,
pageCount
);
dataModel
.
put
(
Pagination
.
PAGINATION_PAGE_NUMS
,
pageNums
);
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
();
final
boolean
hasMultipleUsers
=
Users
.
getInstance
().
hasMultipleUsers
();
if
(
hasMultipleUsers
)
{
if
(
hasMultipleUsers
)
{
setArticlesExProperties
(
articles
,
preference
);
setArticlesExProperties
(
articles
,
preference
);
}
else
{
}
else
{
if
(!
articles
.
isEmpty
())
{
if
(!
articles
.
isEmpty
())
{
final
JSONObject
author
=
articleUtils
.
getAuthor
(
articles
.
get
(
0
));
final
JSONObject
author
=
articleUtils
.
getAuthor
(
articles
.
get
(
0
));
setArticlesExProperties
(
articles
,
author
,
preference
);
setArticlesExProperties
(
articles
,
author
,
preference
);
}
}
}
}
dataModel
.
put
(
Article
.
ARTICLES
,
articles
);
dataModel
.
put
(
Article
.
ARTICLES
,
articles
);
}
catch
(
final
JSONException
e
)
{
}
catch
(
final
JSONException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills index articles failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills index articles failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills index articles failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills index articles failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Fills links.
* Fills links.
*
*
* @param dataModel data model
* @param dataModel data model
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
void
fillLinks
(
final
Map
<
String
,
Object
>
dataModel
)
throws
ServiceException
{
public
void
fillLinks
(
final
Map
<
String
,
Object
>
dataModel
)
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Links"
);
Stopwatchs
.
start
(
"Fill Links"
);
try
{
try
{
final
Map
<
String
,
SortDirection
>
sorts
=
new
HashMap
<
String
,
SortDirection
>();
final
Map
<
String
,
SortDirection
>
sorts
=
new
HashMap
<
String
,
SortDirection
>();
sorts
.
put
(
Link
.
LINK_ORDER
,
SortDirection
.
ASCENDING
);
sorts
.
put
(
Link
.
LINK_ORDER
,
SortDirection
.
ASCENDING
);
final
Query
query
=
new
Query
().
addSort
(
Link
.
LINK_ORDER
,
SortDirection
.
ASCENDING
).
setPageCount
(
1
);
final
Query
query
=
new
Query
().
addSort
(
Link
.
LINK_ORDER
,
SortDirection
.
ASCENDING
).
setPageCount
(
1
);
final
JSONObject
linkResult
=
linkRepository
.
get
(
query
);
final
JSONObject
linkResult
=
linkRepository
.
get
(
query
);
final
List
<
JSONObject
>
links
=
org
.
b3log
.
latke
.
util
.
CollectionUtils
.
jsonArrayToList
(
linkResult
.
getJSONArray
(
Keys
.
RESULTS
));
final
List
<
JSONObject
>
links
=
org
.
b3log
.
latke
.
util
.
CollectionUtils
.
jsonArrayToList
(
linkResult
.
getJSONArray
(
Keys
.
RESULTS
));
dataModel
.
put
(
Link
.
LINKS
,
links
);
dataModel
.
put
(
Link
.
LINKS
,
links
);
}
catch
(
final
JSONException
e
)
{
}
catch
(
final
JSONException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills links failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills links failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills links failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills links failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
/**
/**
* Fills most used tags.
* Fills most used tags.
*
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
void
fillMostUsedTags
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
public
void
fillMostUsedTags
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Most Used Tags"
);
Stopwatchs
.
start
(
"Fill Most Used Tags"
);
try
{
try
{
LOGGER
.
finer
(
"Filling most used tags...."
);
LOGGER
.
finer
(
"Filling most used tags...."
);
final
int
mostUsedTagDisplayCnt
=
preference
.
getInt
(
Preference
.
MOST_USED_TAG_DISPLAY_CNT
);
final
int
mostUsedTagDisplayCnt
=
preference
.
getInt
(
Preference
.
MOST_USED_TAG_DISPLAY_CNT
);
final
List
<
JSONObject
>
tags
=
tagRepository
.
getMostUsedTags
(
mostUsedTagDisplayCnt
);
final
List
<
JSONObject
>
tags
=
tagRepository
.
getMostUsedTags
(
mostUsedTagDisplayCnt
);
tagUtils
.
removeForUnpublishedArticles
(
tags
);
tagUtils
.
removeForUnpublishedArticles
(
tags
);
dataModel
.
put
(
Common
.
MOST_USED_TAGS
,
tags
);
dataModel
.
put
(
Common
.
MOST_USED_TAGS
,
tags
);
}
catch
(
final
JSONException
e
)
{
}
catch
(
final
JSONException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills most used tags failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills most used tags failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills most used tags failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills most used tags failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Fills archive dates.
* Fills archive dates.
*
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
void
fillArchiveDates
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
public
void
fillArchiveDates
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Archive Dates"
);
Stopwatchs
.
start
(
"Fill Archive Dates"
);
try
{
try
{
LOGGER
.
finer
(
"Filling archive dates...."
);
LOGGER
.
finer
(
"Filling archive dates...."
);
final
List
<
JSONObject
>
archiveDates
=
archiveDateRepository
.
getArchiveDates
();
final
List
<
JSONObject
>
archiveDates
=
archiveDateRepository
.
getArchiveDates
();
final
String
localeString
=
preference
.
getString
(
Preference
.
LOCALE_STRING
);
final
String
localeString
=
preference
.
getString
(
Preference
.
LOCALE_STRING
);
final
String
language
=
Locales
.
getLanguage
(
localeString
);
final
String
language
=
Locales
.
getLanguage
(
localeString
);
for
(
final
JSONObject
archiveDate
:
archiveDates
)
{
for
(
final
JSONObject
archiveDate
:
archiveDates
)
{
final
long
time
=
archiveDate
.
getLong
(
ArchiveDate
.
ARCHIVE_TIME
);
final
long
time
=
archiveDate
.
getLong
(
ArchiveDate
.
ARCHIVE_TIME
);
final
String
dateString
=
ArchiveDate
.
DATE_FORMAT
.
format
(
time
);
final
String
dateString
=
ArchiveDate
.
DATE_FORMAT
.
format
(
time
);
final
String
[]
dateStrings
=
dateString
.
split
(
"/"
);
final
String
[]
dateStrings
=
dateString
.
split
(
"/"
);
final
String
year
=
dateStrings
[
0
];
final
String
year
=
dateStrings
[
0
];
final
String
month
=
dateStrings
[
1
];
final
String
month
=
dateStrings
[
1
];
archiveDate
.
put
(
ArchiveDate
.
ARCHIVE_DATE_YEAR
,
year
);
archiveDate
.
put
(
ArchiveDate
.
ARCHIVE_DATE_YEAR
,
year
);
archiveDate
.
put
(
ArchiveDate
.
ARCHIVE_DATE_MONTH
,
month
);
archiveDate
.
put
(
ArchiveDate
.
ARCHIVE_DATE_MONTH
,
month
);
if
(
"en"
.
equals
(
language
))
{
if
(
"en"
.
equals
(
language
))
{
final
String
monthName
=
Dates
.
EN_MONTHS
.
get
(
month
);
final
String
monthName
=
Dates
.
EN_MONTHS
.
get
(
month
);
archiveDate
.
put
(
Common
.
MONTH_NAME
,
monthName
);
archiveDate
.
put
(
Common
.
MONTH_NAME
,
monthName
);
}
}
}
}
dataModel
.
put
(
ArchiveDate
.
ARCHIVE_DATES
,
archiveDates
);
dataModel
.
put
(
ArchiveDate
.
ARCHIVE_DATES
,
archiveDates
);
}
catch
(
final
JSONException
e
)
{
}
catch
(
final
JSONException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills archive dates failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills archive dates failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills archive dates failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills archive dates failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Fills most view count articles.
* Fills most view count articles.
*
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
void
fillMostViewCountArticles
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
public
void
fillMostViewCountArticles
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Most View Articles"
);
Stopwatchs
.
start
(
"Fill Most View Articles"
);
try
{
try
{
LOGGER
.
finer
(
"Filling the most view count articles...."
);
LOGGER
.
finer
(
"Filling the most view count articles...."
);
final
int
mostCommentArticleDisplayCnt
=
preference
.
getInt
(
Preference
.
MOST_VIEW_ARTICLE_DISPLAY_CNT
);
final
int
mostCommentArticleDisplayCnt
=
preference
.
getInt
(
Preference
.
MOST_VIEW_ARTICLE_DISPLAY_CNT
);
final
List
<
JSONObject
>
mostViewCountArticles
=
articleRepository
.
getMostViewCountArticles
(
mostCommentArticleDisplayCnt
);
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
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills most view count articles failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills most view count articles failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Fills most comments articles.
* Fills most comments articles.
*
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
void
fillMostCommentArticles
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
public
void
fillMostCommentArticles
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Most CMMTs Articles"
);
Stopwatchs
.
start
(
"Fill Most CMMTs Articles"
);
try
{
try
{
LOGGER
.
finer
(
"Filling most comment articles...."
);
LOGGER
.
finer
(
"Filling most comment articles...."
);
final
int
mostCommentArticleDisplayCnt
=
preference
.
getInt
(
Preference
.
MOST_COMMENT_ARTICLE_DISPLAY_CNT
);
final
int
mostCommentArticleDisplayCnt
=
preference
.
getInt
(
Preference
.
MOST_COMMENT_ARTICLE_DISPLAY_CNT
);
final
List
<
JSONObject
>
mostCommentArticles
=
articleRepository
.
getMostCommentArticles
(
mostCommentArticleDisplayCnt
);
final
List
<
JSONObject
>
mostCommentArticles
=
articleRepository
.
getMostCommentArticles
(
mostCommentArticleDisplayCnt
);
dataModel
.
put
(
Common
.
MOST_COMMENT_ARTICLES
,
mostCommentArticles
);
dataModel
.
put
(
Common
.
MOST_COMMENT_ARTICLES
,
mostCommentArticles
);
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills most comment articles failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills most comment articles failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Fills post articles recently.
* Fills post articles recently.
*
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
void
fillRecentArticles
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
public
void
fillRecentArticles
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Recent Articles"
);
Stopwatchs
.
start
(
"Fill Recent Articles"
);
try
{
try
{
final
int
recentArticleDisplayCnt
=
preference
.
getInt
(
Preference
.
RECENT_ARTICLE_DISPLAY_CNT
);
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
)
{
}
catch
(
final
JSONException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills recent articles failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills recent articles failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills recent articles failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills recent articles failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Fills post comments recently.
* Fills post comments recently.
*
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
void
fillRecentComments
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
public
void
fillRecentComments
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Recent Comments"
);
Stopwatchs
.
start
(
"Fill Recent Comments"
);
try
{
try
{
LOGGER
.
finer
(
"Filling recent comments...."
);
LOGGER
.
finer
(
"Filling recent comments...."
);
final
int
recentCommentDisplayCnt
=
preference
.
getInt
(
Preference
.
RECENT_COMMENT_DISPLAY_CNT
);
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
)
{
for
(
final
JSONObject
comment
:
recentComments
)
{
final
String
content
=
comment
.
getString
(
Comment
.
COMMENT_CONTENT
).
replaceAll
(
SoloServletListener
.
ENTER_ESC
,
" "
);
final
String
content
=
comment
.
getString
(
Comment
.
COMMENT_CONTENT
).
replaceAll
(
SoloServletListener
.
ENTER_ESC
,
" "
);
comment
.
put
(
Comment
.
COMMENT_CONTENT
,
content
);
comment
.
put
(
Comment
.
COMMENT_CONTENT
,
content
);
comment
.
put
(
Comment
.
COMMENT_NAME
,
StringEscapeUtils
.
escapeHtml
(
comment
.
getString
(
Comment
.
COMMENT_NAME
)));
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
.
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
)
{
}
catch
(
final
JSONException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills recent comments failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills recent comments failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills recent comments failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills recent comments failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Fills footer.ftl.
* Fills footer.ftl.
*
*
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
void
fillBlogFooter
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
public
void
fillBlogFooter
(
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Footer"
);
Stopwatchs
.
start
(
"Fill Footer"
);
try
{
try
{
LOGGER
.
finer
(
"Filling footer...."
);
LOGGER
.
finer
(
"Filling footer...."
);
final
String
blogTitle
=
preference
.
getString
(
Preference
.
BLOG_TITLE
);
final
String
blogTitle
=
preference
.
getString
(
Preference
.
BLOG_TITLE
);
dataModel
.
put
(
Preference
.
BLOG_TITLE
,
blogTitle
);
dataModel
.
put
(
Preference
.
BLOG_TITLE
,
blogTitle
);
final
String
blogHost
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
final
String
blogHost
=
preference
.
getString
(
Preference
.
BLOG_HOST
);
dataModel
.
put
(
Preference
.
BLOG_HOST
,
blogHost
);
dataModel
.
put
(
Preference
.
BLOG_HOST
,
blogHost
);
dataModel
.
put
(
Common
.
VERSION
,
SoloServletListener
.
VERSION
);
dataModel
.
put
(
Common
.
VERSION
,
SoloServletListener
.
VERSION
);
dataModel
.
put
(
Common
.
STATIC_RESOURCE_VERSION
,
Latkes
.
getStaticResourceVersion
());
dataModel
.
put
(
Common
.
STATIC_RESOURCE_VERSION
,
Latkes
.
getStaticResourceVersion
());
dataModel
.
put
(
Common
.
YEAR
,
String
.
valueOf
(
Calendar
.
getInstance
().
get
(
Calendar
.
YEAR
)));
dataModel
.
put
(
Common
.
YEAR
,
String
.
valueOf
(
Calendar
.
getInstance
().
get
(
Calendar
.
YEAR
)));
dataModel
.
put
(
Keys
.
Server
.
STATIC_SERVER
,
Latkes
.
getStaticServer
());
dataModel
.
put
(
Keys
.
Server
.
STATIC_SERVER
,
Latkes
.
getStaticServer
());
dataModel
.
put
(
Keys
.
Server
.
SERVER
,
Latkes
.
getServer
());
dataModel
.
put
(
Keys
.
Server
.
SERVER
,
Latkes
.
getServer
());
// Activates plugins
// Activates plugins
try
{
try
{
final
ViewLoadEventData
data
=
new
ViewLoadEventData
();
final
ViewLoadEventData
data
=
new
ViewLoadEventData
();
data
.
setViewName
(
"footer.ftl"
);
data
.
setViewName
(
"footer.ftl"
);
data
.
setDataModel
(
dataModel
);
data
.
setDataModel
(
dataModel
);
EventManager
.
getInstance
().
fireEventSynchronously
(
new
Event
<
ViewLoadEventData
>(
AbstractAction
.
FREEMARKER_ACTION
,
data
));
EventManager
.
getInstance
().
fireEventSynchronously
(
new
Event
<
ViewLoadEventData
>(
AbstractAction
.
FREEMARKER_ACTION
,
data
));
if
(
Strings
.
isEmptyOrNull
((
String
)
dataModel
.
get
(
Plugin
.
PLUGINS
)))
{
if
(
Strings
.
isEmptyOrNull
((
String
)
dataModel
.
get
(
Plugin
.
PLUGINS
)))
{
// There is no plugin for this template, fill ${plugins} with blank.
// There is no plugin for this template, fill ${plugins} with blank.
dataModel
.
put
(
Plugin
.
PLUGINS
,
""
);
dataModel
.
put
(
Plugin
.
PLUGINS
,
""
);
}
}
}
catch
(
final
EventException
e
)
{
}
catch
(
final
EventException
e
)
{
LOGGER
.
log
(
Level
.
WARNING
,
"Event[FREEMARKER_ACTION] handle failed, ignores this exception for kernel health"
,
e
);
LOGGER
.
log
(
Level
.
WARNING
,
"Event[FREEMARKER_ACTION] handle failed, ignores this exception for kernel health"
,
e
);
}
}
}
catch
(
final
JSONException
e
)
{
}
catch
(
final
JSONException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills blog footer failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills blog footer failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Fills header.ftl.
* Fills header.ftl.
*
*
* @param request the specified HTTP servlet request
* @param request the specified HTTP servlet request
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
void
fillBlogHeader
(
final
HttpServletRequest
request
,
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
public
void
fillBlogHeader
(
final
HttpServletRequest
request
,
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Header"
);
Stopwatchs
.
start
(
"Fill Header"
);
try
{
try
{
LOGGER
.
fine
(
"Filling header...."
);
LOGGER
.
fine
(
"Filling header...."
);
dataModel
.
put
(
Preference
.
ARTICLE_LIST_DISPLAY_COUNT
,
preference
.
getInt
(
Preference
.
ARTICLE_LIST_DISPLAY_COUNT
));
dataModel
.
put
(
Preference
.
ARTICLE_LIST_DISPLAY_COUNT
,
preference
.
getInt
(
Preference
.
ARTICLE_LIST_DISPLAY_COUNT
));
dataModel
.
put
(
Preference
.
ARTICLE_LIST_PAGINATION_WINDOW_SIZE
,
dataModel
.
put
(
Preference
.
ARTICLE_LIST_PAGINATION_WINDOW_SIZE
,
preference
.
getInt
(
Preference
.
ARTICLE_LIST_PAGINATION_WINDOW_SIZE
));
preference
.
getInt
(
Preference
.
ARTICLE_LIST_PAGINATION_WINDOW_SIZE
));
dataModel
.
put
(
Preference
.
LOCALE_STRING
,
preference
.
getString
(
Preference
.
LOCALE_STRING
));
dataModel
.
put
(
Preference
.
LOCALE_STRING
,
preference
.
getString
(
Preference
.
LOCALE_STRING
));
dataModel
.
put
(
Preference
.
BLOG_TITLE
,
preference
.
getString
(
Preference
.
BLOG_TITLE
));
dataModel
.
put
(
Preference
.
BLOG_TITLE
,
preference
.
getString
(
Preference
.
BLOG_TITLE
));
dataModel
.
put
(
Preference
.
BLOG_SUBTITLE
,
preference
.
getString
(
Preference
.
BLOG_SUBTITLE
));
dataModel
.
put
(
Preference
.
BLOG_SUBTITLE
,
preference
.
getString
(
Preference
.
BLOG_SUBTITLE
));
dataModel
.
put
(
Preference
.
HTML_HEAD
,
preference
.
getString
(
Preference
.
HTML_HEAD
));
dataModel
.
put
(
Preference
.
HTML_HEAD
,
preference
.
getString
(
Preference
.
HTML_HEAD
));
dataModel
.
put
(
Preference
.
META_KEYWORDS
,
preference
.
getString
(
Preference
.
META_KEYWORDS
));
dataModel
.
put
(
Preference
.
META_KEYWORDS
,
preference
.
getString
(
Preference
.
META_KEYWORDS
));
dataModel
.
put
(
Preference
.
META_DESCRIPTION
,
preference
.
getString
(
Preference
.
META_DESCRIPTION
));
dataModel
.
put
(
Preference
.
META_DESCRIPTION
,
preference
.
getString
(
Preference
.
META_DESCRIPTION
));
dataModel
.
put
(
Common
.
YEAR
,
String
.
valueOf
(
Calendar
.
getInstance
().
get
(
Calendar
.
YEAR
)));
dataModel
.
put
(
Common
.
YEAR
,
String
.
valueOf
(
Calendar
.
getInstance
().
get
(
Calendar
.
YEAR
)));
final
String
noticeBoard
=
preference
.
getString
(
Preference
.
NOTICE_BOARD
);
final
String
noticeBoard
=
preference
.
getString
(
Preference
.
NOTICE_BOARD
);
dataModel
.
put
(
Preference
.
NOTICE_BOARD
,
noticeBoard
);
dataModel
.
put
(
Preference
.
NOTICE_BOARD
,
noticeBoard
);
final
Query
query
=
new
Query
().
setPageCount
(
1
);
final
Query
query
=
new
Query
().
setPageCount
(
1
);
final
JSONObject
result
=
userRepository
.
get
(
query
);
final
JSONObject
result
=
userRepository
.
get
(
query
);
final
JSONArray
users
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
users
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
List
<
JSONObject
>
userList
=
CollectionUtils
.
jsonArrayToList
(
users
);
final
List
<
JSONObject
>
userList
=
CollectionUtils
.
jsonArrayToList
(
users
);
dataModel
.
put
(
User
.
USERS
,
userList
);
dataModel
.
put
(
User
.
USERS
,
userList
);
for
(
final
JSONObject
user
:
userList
)
{
for
(
final
JSONObject
user
:
userList
)
{
user
.
remove
(
User
.
USER_EMAIL
);
user
.
remove
(
User
.
USER_EMAIL
);
}
}
final
String
skinDirName
=
(
String
)
request
.
getAttribute
(
Keys
.
TEMAPLTE_DIR_NAME
);
final
String
skinDirName
=
(
String
)
request
.
getAttribute
(
Keys
.
TEMAPLTE_DIR_NAME
);
dataModel
.
put
(
Skin
.
SKIN_DIR_NAME
,
skinDirName
);
dataModel
.
put
(
Skin
.
SKIN_DIR_NAME
,
skinDirName
);
Keys
.
fillServer
(
dataModel
);
Keys
.
fillServer
(
dataModel
);
fillMinified
(
dataModel
);
fillMinified
(
dataModel
);
fillPageNavigations
(
dataModel
);
fillPageNavigations
(
dataModel
);
fillStatistic
(
dataModel
);
fillStatistic
(
dataModel
);
}
catch
(
final
JSONException
e
)
{
}
catch
(
final
JSONException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills blog header failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills blog header failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills blog header failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills blog header failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
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
)
{
public
void
fillMinified
(
final
Map
<
String
,
Object
>
dataModel
)
{
switch
(
Latkes
.
getRuntimeMode
())
{
switch
(
Latkes
.
getRuntimeMode
())
{
case
DEVELOPMENT:
case
DEVELOPMENT:
dataModel
.
put
(
Common
.
MINI_POSTFIX
,
""
);
dataModel
.
put
(
Common
.
MINI_POSTFIX
,
""
);
break
;
break
;
case
PRODUCTION:
case
PRODUCTION:
dataModel
.
put
(
Common
.
MINI_POSTFIX
,
Common
.
MINI_POSTFIX_VALUE
);
dataModel
.
put
(
Common
.
MINI_POSTFIX
,
Common
.
MINI_POSTFIX_VALUE
);
break
;
break
;
default
:
default
:
throw
new
AssertionError
();
throw
new
AssertionError
();
}
}
}
}
/**
/**
* Fills side.ftl.
* Fills side.ftl.
*
*
* @param request the specified HTTP servlet request
* @param request the specified HTTP servlet request
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
void
fillSide
(
final
HttpServletRequest
request
,
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
public
void
fillSide
(
final
HttpServletRequest
request
,
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Side"
);
Stopwatchs
.
start
(
"Fill Side"
);
try
{
try
{
LOGGER
.
fine
(
"Filling side...."
);
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
)
{
if
(
null
==
template
)
{
LOGGER
.
fine
(
"The skin dose not contain [side.ftl] template"
);
LOGGER
.
fine
(
"The skin dose not contain [side.ftl] template"
);
return
;
return
;
}
}
// TODO: fillRecentArticles(dataModel, preference);
// TODO: fillRecentArticles(dataModel, preference);
if
(
Templates
.
hasExpression
(
template
,
"<#list links as link>"
))
{
if
(
Templates
.
hasExpression
(
template
,
"<#list links as link>"
))
{
fillLinks
(
dataModel
);
fillLinks
(
dataModel
);
}
}
if
(
Templates
.
hasExpression
(
template
,
"<#list recentComments as comment>"
))
{
if
(
Templates
.
hasExpression
(
template
,
"<#list recentComments as comment>"
))
{
fillRecentComments
(
dataModel
,
preference
);
fillRecentComments
(
dataModel
,
preference
);
}
}
if
(
Templates
.
hasExpression
(
template
,
"<#list mostUsedTags as tag>"
))
{
if
(
Templates
.
hasExpression
(
template
,
"<#list mostUsedTags as tag>"
))
{
fillMostUsedTags
(
dataModel
,
preference
);
fillMostUsedTags
(
dataModel
,
preference
);
}
}
if
(
Templates
.
hasExpression
(
template
,
"<#list mostCommentArticles as article>"
))
{
if
(
Templates
.
hasExpression
(
template
,
"<#list mostCommentArticles as article>"
))
{
fillMostCommentArticles
(
dataModel
,
preference
);
fillMostCommentArticles
(
dataModel
,
preference
);
}
}
if
(
Templates
.
hasExpression
(
template
,
"<#list mostViewCountArticles as article>"
))
{
if
(
Templates
.
hasExpression
(
template
,
"<#list mostViewCountArticles as article>"
))
{
fillMostViewCountArticles
(
dataModel
,
preference
);
fillMostViewCountArticles
(
dataModel
,
preference
);
}
}
if
(
Templates
.
hasExpression
(
template
,
"<#list archiveDates as archiveDate>"
))
{
if
(
Templates
.
hasExpression
(
template
,
"<#list archiveDates as archiveDate>"
))
{
fillArchiveDates
(
dataModel
,
preference
);
fillArchiveDates
(
dataModel
,
preference
);
}
}
}
catch
(
final
ServiceException
e
)
{
}
catch
(
final
ServiceException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills side failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills side failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Fills the specified template.
* Fills the specified template.
*
*
* @param template the specified template
* @param template the specified template
* @param dataModel data model
* @param dataModel data model
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
void
fillUserTemplate
(
final
Template
template
,
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
public
void
fillUserTemplate
(
final
Template
template
,
final
Map
<
String
,
Object
>
dataModel
,
final
JSONObject
preference
)
throws
ServiceException
{
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill User Template[name="
+
template
.
getName
()
+
"]"
);
Stopwatchs
.
start
(
"Fill User Template[name="
+
template
.
getName
()
+
"]"
);
try
{
try
{
LOGGER
.
log
(
Level
.
FINE
,
"Filling user template[name{0}]"
,
template
.
getName
());
LOGGER
.
log
(
Level
.
FINE
,
"Filling user template[name{0}]"
,
template
.
getName
());
if
(
Templates
.
hasExpression
(
template
,
"<#list links as link>"
))
{
if
(
Templates
.
hasExpression
(
template
,
"<#list links as link>"
))
{
fillLinks
(
dataModel
);
fillLinks
(
dataModel
);
}
}
if
(
Templates
.
hasExpression
(
template
,
"<#list recentComments as comment>"
))
{
if
(
Templates
.
hasExpression
(
template
,
"<#list recentComments as comment>"
))
{
fillRecentComments
(
dataModel
,
preference
);
fillRecentComments
(
dataModel
,
preference
);
}
}
if
(
Templates
.
hasExpression
(
template
,
"<#list mostUsedTags as tag>"
))
{
if
(
Templates
.
hasExpression
(
template
,
"<#list mostUsedTags as tag>"
))
{
fillMostUsedTags
(
dataModel
,
preference
);
fillMostUsedTags
(
dataModel
,
preference
);
}
}
if
(
Templates
.
hasExpression
(
template
,
"<#list mostCommentArticles as article>"
))
{
if
(
Templates
.
hasExpression
(
template
,
"<#list mostCommentArticles as article>"
))
{
fillMostCommentArticles
(
dataModel
,
preference
);
fillMostCommentArticles
(
dataModel
,
preference
);
}
}
if
(
Templates
.
hasExpression
(
template
,
"<#list mostViewCountArticles as article>"
))
{
if
(
Templates
.
hasExpression
(
template
,
"<#list mostViewCountArticles as article>"
))
{
fillMostViewCountArticles
(
dataModel
,
preference
);
fillMostViewCountArticles
(
dataModel
,
preference
);
}
}
if
(
Templates
.
hasExpression
(
template
,
"<#list archiveDates as archiveDate>"
))
{
if
(
Templates
.
hasExpression
(
template
,
"<#list archiveDates as archiveDate>"
))
{
fillArchiveDates
(
dataModel
,
preference
);
fillArchiveDates
(
dataModel
,
preference
);
}
}
final
String
noticeBoard
=
preference
.
getString
(
Preference
.
NOTICE_BOARD
);
final
String
noticeBoard
=
preference
.
getString
(
Preference
.
NOTICE_BOARD
);
dataModel
.
put
(
Preference
.
NOTICE_BOARD
,
noticeBoard
);
dataModel
.
put
(
Preference
.
NOTICE_BOARD
,
noticeBoard
);
}
catch
(
final
JSONException
e
)
{
}
catch
(
final
JSONException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills user template failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills user template failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Fills page navigations.
* Fills page navigations.
*
*
* @param dataModel data model
* @param dataModel data model
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
private
void
fillPageNavigations
(
final
Map
<
String
,
Object
>
dataModel
)
throws
ServiceException
{
private
void
fillPageNavigations
(
final
Map
<
String
,
Object
>
dataModel
)
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Navigations"
);
Stopwatchs
.
start
(
"Fill Navigations"
);
try
{
try
{
LOGGER
.
finer
(
"Filling page navigations...."
);
LOGGER
.
finer
(
"Filling page navigations...."
);
final
List
<
JSONObject
>
pages
=
pageRepository
.
getPages
();
final
List
<
JSONObject
>
pages
=
pageRepository
.
getPages
();
for
(
final
JSONObject
page
:
pages
)
{
for
(
final
JSONObject
page
:
pages
)
{
if
(
"page"
.
equals
(
page
.
optString
(
Page
.
PAGE_TYPE
)))
{
if
(
"page"
.
equals
(
page
.
optString
(
Page
.
PAGE_TYPE
)))
{
final
String
permalink
=
page
.
optString
(
Page
.
PAGE_PERMALINK
);
final
String
permalink
=
page
.
optString
(
Page
.
PAGE_PERMALINK
);
page
.
put
(
Page
.
PAGE_PERMALINK
,
Latkes
.
getServePath
()
+
permalink
);
page
.
put
(
Page
.
PAGE_PERMALINK
,
Latkes
.
getServePath
()
+
permalink
);
}
}
}
}
dataModel
.
put
(
Common
.
PAGE_NAVIGATIONS
,
pages
);
dataModel
.
put
(
Common
.
PAGE_NAVIGATIONS
,
pages
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills page navigations failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills page navigations failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Fills statistic.
* Fills statistic.
*
*
* @param dataModel data model
* @param dataModel data model
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
private
void
fillStatistic
(
final
Map
<
String
,
Object
>
dataModel
)
throws
ServiceException
{
private
void
fillStatistic
(
final
Map
<
String
,
Object
>
dataModel
)
throws
ServiceException
{
Stopwatchs
.
start
(
"Fill Statistic"
);
Stopwatchs
.
start
(
"Fill Statistic"
);
try
{
try
{
LOGGER
.
finer
(
"Filling statistic...."
);
LOGGER
.
finer
(
"Filling statistic...."
);
final
JSONObject
statistic
=
statisticRepository
.
get
(
Statistic
.
STATISTIC
);
final
JSONObject
statistic
=
statisticRepository
.
get
(
Statistic
.
STATISTIC
);
dataModel
.
put
(
Statistic
.
STATISTIC
,
statistic
);
dataModel
.
put
(
Statistic
.
STATISTIC
,
statistic
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills statistic failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Fills statistic failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
finally
{
}
finally
{
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Sets some extra properties into the specified article with the specified author and preference, performs content and
* Sets some extra properties into the specified article with the specified author and preference, performs content and
* abstract editor processing.
* abstract editor processing.
*
*
* <p>
* <p>
* Article ext properties:
* Article ext properties:
* <pre>
* <pre>
* {
* {
* ....,
* ....,
* "authorName": "",
* "authorName": "",
* "authorId": "",
* "authorId": "",
* "hasUpdated": boolean
* "hasUpdated": boolean
* }
* }
* </pre>
* </pre>
* </p>
* </p>
*
*
* @param article the specified article
* @param article the specified article
* @param author the specified author
* @param author the specified author
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
* @see #setArticlesExProperties(java.util.List, org.json.JSONObject)
* @see #setArticlesExProperties(java.util.List, org.json.JSONObject)
*/
*/
private
void
setArticleExProperties
(
final
JSONObject
article
,
final
JSONObject
author
,
final
JSONObject
preference
)
private
void
setArticleExProperties
(
final
JSONObject
article
,
final
JSONObject
author
,
final
JSONObject
preference
)
throws
ServiceException
{
throws
ServiceException
{
try
{
try
{
final
String
authorName
=
author
.
getString
(
User
.
USER_NAME
);
final
String
authorName
=
author
.
getString
(
User
.
USER_NAME
);
article
.
put
(
Common
.
AUTHOR_NAME
,
authorName
);
article
.
put
(
Common
.
AUTHOR_NAME
,
authorName
);
final
String
authorId
=
author
.
getString
(
Keys
.
OBJECT_ID
);
final
String
authorId
=
author
.
getString
(
Keys
.
OBJECT_ID
);
article
.
put
(
Common
.
AUTHOR_ID
,
authorId
);
article
.
put
(
Common
.
AUTHOR_ID
,
authorId
);
if
(
preference
.
getBoolean
(
Preference
.
ENABLE_ARTICLE_UPDATE_HINT
))
{
if
(
preference
.
getBoolean
(
Preference
.
ENABLE_ARTICLE_UPDATE_HINT
))
{
article
.
put
(
Common
.
HAS_UPDATED
,
articleUtils
.
hasUpdated
(
article
));
article
.
put
(
Common
.
HAS_UPDATED
,
articleUtils
.
hasUpdated
(
article
));
}
else
{
}
else
{
article
.
put
(
Common
.
HAS_UPDATED
,
false
);
article
.
put
(
Common
.
HAS_UPDATED
,
false
);
}
}
processArticleAbstract
(
preference
,
article
);
processArticleAbstract
(
preference
,
article
);
articleQueryService
.
markdown
(
article
);
articleQueryService
.
markdown
(
article
);
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Sets article extra properties failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Sets article extra properties failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
}
}
}
/**
/**
* Sets some extra properties into the specified article with the specified preference, performs content and
* Sets some extra properties into the specified article with the specified preference, performs content and
* abstract editor processing.
* abstract editor processing.
*
*
* <p>
* <p>
* Article ext properties:
* Article ext properties:
* <pre>
* <pre>
* {
* {
* ....,
* ....,
* "authorName": "",
* "authorName": "",
* "authorId": "",
* "authorId": "",
* "hasUpdated": boolean
* "hasUpdated": boolean
* }
* }
* </pre>
* </pre>
* </p>
* </p>
*
*
* @param article the specified article
* @param article the specified article
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
* @see #setArticlesExProperties(java.util.List, org.json.JSONObject)
* @see #setArticlesExProperties(java.util.List, org.json.JSONObject)
*/
*/
private
void
setArticleExProperties
(
final
JSONObject
article
,
final
JSONObject
preference
)
throws
ServiceException
{
private
void
setArticleExProperties
(
final
JSONObject
article
,
final
JSONObject
preference
)
throws
ServiceException
{
try
{
try
{
final
JSONObject
author
=
articleUtils
.
getAuthor
(
article
);
final
JSONObject
author
=
articleUtils
.
getAuthor
(
article
);
final
String
authorName
=
author
.
getString
(
User
.
USER_NAME
);
final
String
authorName
=
author
.
getString
(
User
.
USER_NAME
);
article
.
put
(
Common
.
AUTHOR_NAME
,
authorName
);
article
.
put
(
Common
.
AUTHOR_NAME
,
authorName
);
final
String
authorId
=
author
.
getString
(
Keys
.
OBJECT_ID
);
final
String
authorId
=
author
.
getString
(
Keys
.
OBJECT_ID
);
article
.
put
(
Common
.
AUTHOR_ID
,
authorId
);
article
.
put
(
Common
.
AUTHOR_ID
,
authorId
);
if
(
preference
.
getBoolean
(
Preference
.
ENABLE_ARTICLE_UPDATE_HINT
))
{
if
(
preference
.
getBoolean
(
Preference
.
ENABLE_ARTICLE_UPDATE_HINT
))
{
article
.
put
(
Common
.
HAS_UPDATED
,
articleUtils
.
hasUpdated
(
article
));
article
.
put
(
Common
.
HAS_UPDATED
,
articleUtils
.
hasUpdated
(
article
));
}
else
{
}
else
{
article
.
put
(
Common
.
HAS_UPDATED
,
false
);
article
.
put
(
Common
.
HAS_UPDATED
,
false
);
}
}
processArticleAbstract
(
preference
,
article
);
processArticleAbstract
(
preference
,
article
);
articleQueryService
.
markdown
(
article
);
articleQueryService
.
markdown
(
article
);
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Sets article extra properties failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Sets article extra properties failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
}
}
}
/**
/**
* Sets some extra properties into the specified article with the specified
* Sets some extra properties into the specified article with the specified
* author and preference.
* author and preference.
*
*
* <p>
* <p>
* The batch version of method
* The batch version of method
* {@linkplain #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)}.
* {@linkplain #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)}.
* </p>
* </p>
*
*
* <p>
* <p>
* Article ext properties:
* Article ext properties:
* <pre>
* <pre>
* {
* {
* ....,
* ....,
* "authorName": "",
* "authorName": "",
* "authorId": "",
* "authorId": "",
* "hasUpdated": boolean
* "hasUpdated": boolean
* }
* }
* </pre>
* </pre>
* </p>
* </p>
*
*
* @param articles the specified articles
* @param articles the specified articles
* @param author the specified author
* @param author the specified author
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
* @see #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)
* @see #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)
*/
*/
public
void
setArticlesExProperties
(
final
List
<
JSONObject
>
articles
,
final
JSONObject
author
,
final
JSONObject
preference
)
public
void
setArticlesExProperties
(
final
List
<
JSONObject
>
articles
,
final
JSONObject
author
,
final
JSONObject
preference
)
throws
ServiceException
{
throws
ServiceException
{
for
(
final
JSONObject
article
:
articles
)
{
for
(
final
JSONObject
article
:
articles
)
{
setArticleExProperties
(
article
,
author
,
preference
);
setArticleExProperties
(
article
,
author
,
preference
);
}
}
}
}
/**
/**
* Sets some extra properties into the specified article with the specified
* Sets some extra properties into the specified article with the specified
* preference.
* preference.
*
*
* <p>
* <p>
* The batch version of method
* The batch version of method
* {@linkplain #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)}.
* {@linkplain #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)}.
* </p>
* </p>
*
*
* <p>
* <p>
* Article ext properties:
* Article ext properties:
* <pre>
* <pre>
* {
* {
* ....,
* ....,
* "authorName": "",
* "authorName": "",
* "authorId": "",
* "authorId": "",
* "hasUpdated": boolean
* "hasUpdated": boolean
* }
* }
* </pre>
* </pre>
* </p>
* </p>
*
*
* @param articles the specified articles
* @param articles the specified articles
* @param preference the specified preference
* @param preference the specified preference
* @throws ServiceException service exception
* @throws ServiceException service exception
* @see #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)
* @see #setArticleExProperties(org.json.JSONObject, org.json.JSONObject)
*/
*/
public
void
setArticlesExProperties
(
final
List
<
JSONObject
>
articles
,
final
JSONObject
preference
)
public
void
setArticlesExProperties
(
final
List
<
JSONObject
>
articles
,
final
JSONObject
preference
)
throws
ServiceException
{
throws
ServiceException
{
for
(
final
JSONObject
article
:
articles
)
{
for
(
final
JSONObject
article
:
articles
)
{
setArticleExProperties
(
article
,
preference
);
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>
* <p>
* <ul>
* <ul>
* <li>If the abstract is {@code null}, sets it with ""</li>
* <li>If the abstract is {@code null}, sets it with ""</li>
* <li>If user configured preference "titleOnly", sets the abstract with ""</li>
* <li>If user configured preference "titleOnly", sets the abstract with ""</li>
* <li>If user configured preference "titleAndContent", sets the abstract with the content of the article</li>
* <li>If user configured preference "titleAndContent", sets the abstract with the content of the article</li>
* </ul>
* </ul>
* </p>
* </p>
*
*
* @param preference the specified preference
* @param preference the specified preference
* @param article the specified article
* @param article the specified article
*/
*/
private
void
processArticleAbstract
(
final
JSONObject
preference
,
final
JSONObject
article
)
{
private
void
processArticleAbstract
(
final
JSONObject
preference
,
final
JSONObject
article
)
{
final
String
articleAbstract
=
article
.
optString
(
Article
.
ARTICLE_ABSTRACT
,
null
);
final
String
articleAbstract
=
article
.
optString
(
Article
.
ARTICLE_ABSTRACT
,
null
);
if
(
null
==
articleAbstract
)
{
if
(
null
==
articleAbstract
)
{
article
.
put
(
Article
.
ARTICLE_ABSTRACT
,
""
);
article
.
put
(
Article
.
ARTICLE_ABSTRACT
,
""
);
}
}
final
String
articleListStyle
=
preference
.
optString
(
Preference
.
ARTICLE_LIST_STYLE
);
final
String
articleListStyle
=
preference
.
optString
(
Preference
.
ARTICLE_LIST_STYLE
);
if
(
"titleOnly"
.
equals
(
articleListStyle
))
{
if
(
"titleOnly"
.
equals
(
articleListStyle
))
{
article
.
put
(
Article
.
ARTICLE_ABSTRACT
,
""
);
article
.
put
(
Article
.
ARTICLE_ABSTRACT
,
""
);
}
else
if
(
"titleAndContent"
.
equals
(
articleListStyle
))
{
}
else
if
(
"titleAndContent"
.
equals
(
articleListStyle
))
{
article
.
put
(
Article
.
ARTICLE_ABSTRACT
,
article
.
optString
(
Article
.
ARTICLE_CONTENT
));
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
()
{
public
static
Filler
getInstance
()
{
return
SingletonHolder
.
SINGLETON
;
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>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.0, Jan 12, 2011
* @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
()
{
}
}
}
}
}
}
core/src/main/java/org/b3log/solo/repository/impl/ArchiveDateArticleRepositoryImpl.java
View file @
65f8a5e9
/*
/*
* 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.AbstractRepository
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.solo.model.Article
;
import
org.b3log.solo.model.Article
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.solo.model.ArchiveDate
;
import
org.b3log.solo.model.ArchiveDate
;
import
org.b3log.solo.repository.ArchiveDateArticleRepository
;
import
org.b3log.solo.repository.ArchiveDateArticleRepository
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
/**
/**
* Archive date-Article relation repository.
* Archive date-Article relation repository.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.6, Nov 9, 2011
* @version 1.0.0.6, Nov 9, 2011
* @since 0.3.1
* @since 0.3.1
*/
*/
public
final
class
ArchiveDateArticleRepositoryImpl
extends
AbstractRepository
implements
ArchiveDateArticleRepository
{
public
final
class
ArchiveDateArticleRepositoryImpl
extends
AbstractRepository
implements
ArchiveDateArticleRepository
{
/**
/**
* Singleton.
* Singleton.
*/
*/
private
static
final
ArchiveDateArticleRepositoryImpl
SINGLETON
=
private
static
final
ArchiveDateArticleRepositoryImpl
SINGLETON
=
new
ArchiveDateArticleRepositoryImpl
(
ArchiveDate
.
ARCHIVE_DATE
+
"_"
+
Article
.
ARTICLE
);
new
ArchiveDateArticleRepositoryImpl
(
ArchiveDate
.
ARCHIVE_DATE
+
"_"
+
Article
.
ARTICLE
);
@Override
@Override
public
JSONObject
getByArchiveDateId
(
final
String
archiveDateId
,
final
int
currentPageNum
,
final
int
pageSize
)
public
JSONObject
getByArchiveDateId
(
final
String
archiveDateId
,
final
int
currentPageNum
,
final
int
pageSize
)
throws
RepositoryException
{
throws
RepositoryException
{
final
Query
query
=
new
Query
().
addFilter
(
ArchiveDate
.
ARCHIVE_DATE
+
"_"
+
Keys
.
OBJECT_ID
,
final
Query
query
=
new
Query
().
addFilter
(
ArchiveDate
.
ARCHIVE_DATE
+
"_"
+
Keys
.
OBJECT_ID
,
FilterOperator
.
EQUAL
,
archiveDateId
).
FilterOperator
.
EQUAL
,
archiveDateId
).
addSort
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
,
addSort
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
,
SortDirection
.
DESCENDING
).
SortDirection
.
DESCENDING
).
setCurrentPageNum
(
currentPageNum
).
setCurrentPageNum
(
currentPageNum
).
setPageSize
(
pageSize
).
setPageSize
(
pageSize
).
setPageCount
(
1
);
setPageCount
(
1
);
return
get
(
query
);
return
get
(
query
);
}
}
@Override
@Override
public
JSONObject
getByArticleId
(
final
String
articleId
)
throws
RepositoryException
{
public
JSONObject
getByArticleId
(
final
String
articleId
)
throws
RepositoryException
{
final
Query
query
=
new
Query
();
final
Query
query
=
new
Query
();
query
.
addFilter
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
,
FilterOperator
.
EQUAL
,
articleId
);
query
.
addFilter
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
,
FilterOperator
.
EQUAL
,
articleId
);
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
);
}
}
/**
/**
* Gets the {@link ArchiveDateArticleRepositoryImpl} singleton.
* Gets the {@link ArchiveDateArticleRepositoryImpl} singleton.
*
*
* @return the singleton
* @return the singleton
*/
*/
public
static
ArchiveDateArticleRepositoryImpl
getInstance
()
{
public
static
ArchiveDateArticleRepositoryImpl
getInstance
()
{
return
SINGLETON
;
return
SINGLETON
;
}
}
/**
/**
* Private constructor.
* Private constructor.
*
*
* @param name the specified name
* @param name the specified name
*/
*/
private
ArchiveDateArticleRepositoryImpl
(
final
String
name
)
{
private
ArchiveDateArticleRepositoryImpl
(
final
String
name
)
{
super
(
name
);
super
(
name
);
}
}
}
}
core/src/main/java/org/b3log/solo/repository/impl/ArchiveDateRepositoryImpl.java
View file @
65f8a5e9
/*
/*
* 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.AbstractRepository
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.util.CollectionUtils
;
import
org.b3log.latke.util.CollectionUtils
;
import
org.b3log.solo.model.ArchiveDate
;
import
org.b3log.solo.model.ArchiveDate
;
import
org.b3log.solo.repository.ArchiveDateRepository
;
import
org.b3log.solo.repository.ArchiveDateRepository
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
/**
/**
* Archive date repository.
* Archive date repository.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.6, Dec 31, 2011
* @version 1.0.0.6, Dec 31, 2011
* @since 0.3.1
* @since 0.3.1
*/
*/
public
final
class
ArchiveDateRepositoryImpl
extends
AbstractRepository
implements
ArchiveDateRepository
{
public
final
class
ArchiveDateRepositoryImpl
extends
AbstractRepository
implements
ArchiveDateRepository
{
/**
/**
* Logger.
* Logger.
*/
*/
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
ArchiveDateRepositoryImpl
.
class
.
getName
());
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
ArchiveDateRepositoryImpl
.
class
.
getName
());
/**
/**
* Singleton.
* Singleton.
*/
*/
private
static
final
ArchiveDateRepositoryImpl
SINGLETON
=
new
ArchiveDateRepositoryImpl
(
ArchiveDate
.
ARCHIVE_DATE
);
private
static
final
ArchiveDateRepositoryImpl
SINGLETON
=
new
ArchiveDateRepositoryImpl
(
ArchiveDate
.
ARCHIVE_DATE
);
@Override
@Override
public
JSONObject
getByArchiveDate
(
final
String
archiveDate
)
throws
RepositoryException
{
public
JSONObject
getByArchiveDate
(
final
String
archiveDate
)
throws
RepositoryException
{
long
time
=
0L
;
long
time
=
0L
;
try
{
try
{
time
=
ArchiveDate
.
DATE_FORMAT
.
parse
(
archiveDate
).
getTime
();
time
=
ArchiveDate
.
DATE_FORMAT
.
parse
(
archiveDate
).
getTime
();
}
catch
(
final
ParseException
e
)
{
}
catch
(
final
ParseException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Can not parse archive date ["
+
archiveDate
+
"]"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Can not parse archive date ["
+
archiveDate
+
"]"
,
e
);
throw
new
RepositoryException
(
"Can not parse archive date ["
+
archiveDate
+
"]"
);
throw
new
RepositoryException
(
"Can not parse archive date ["
+
archiveDate
+
"]"
);
}
}
final
Query
query
=
new
Query
();
final
Query
query
=
new
Query
();
query
.
addFilter
(
ArchiveDate
.
ARCHIVE_TIME
,
FilterOperator
.
EQUAL
,
time
).
setPageCount
(
1
);
query
.
addFilter
(
ArchiveDate
.
ARCHIVE_TIME
,
FilterOperator
.
EQUAL
,
time
).
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
>
getArchiveDates
()
throws
RepositoryException
{
public
List
<
JSONObject
>
getArchiveDates
()
throws
RepositoryException
{
final
org
.
b3log
.
latke
.
repository
.
Query
query
=
final
org
.
b3log
.
latke
.
repository
.
Query
query
=
new
Query
().
addSort
(
ArchiveDate
.
ARCHIVE_TIME
,
SortDirection
.
DESCENDING
).
setPageCount
(
1
);
new
Query
().
addSort
(
ArchiveDate
.
ARCHIVE_TIME
,
SortDirection
.
DESCENDING
).
setPageCount
(
1
);
final
JSONObject
result
=
get
(
query
);
final
JSONObject
result
=
get
(
query
);
final
JSONArray
archiveDates
=
result
.
optJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
archiveDates
=
result
.
optJSONArray
(
Keys
.
RESULTS
);
final
List
<
JSONObject
>
ret
=
CollectionUtils
.
jsonArrayToList
(
archiveDates
);
final
List
<
JSONObject
>
ret
=
CollectionUtils
.
jsonArrayToList
(
archiveDates
);
removeForUnpublishedArticles
(
ret
);
removeForUnpublishedArticles
(
ret
);
return
ret
;
return
ret
;
}
}
/**
/**
* Removes archive dates of unpublished articles from the specified archive
* Removes archive dates of unpublished articles from the specified archive
* dates.
* dates.
*
*
* @param archiveDates the specified archive dates
* @param archiveDates the specified archive dates
* @throws RepositoryException repository exception
* @throws RepositoryException repository exception
*/
*/
private
void
removeForUnpublishedArticles
(
final
List
<
JSONObject
>
archiveDates
)
throws
RepositoryException
{
private
void
removeForUnpublishedArticles
(
final
List
<
JSONObject
>
archiveDates
)
throws
RepositoryException
{
final
Iterator
<
JSONObject
>
iterator
=
archiveDates
.
iterator
();
final
Iterator
<
JSONObject
>
iterator
=
archiveDates
.
iterator
();
while
(
iterator
.
hasNext
())
{
while
(
iterator
.
hasNext
())
{
final
JSONObject
archiveDate
=
iterator
.
next
();
final
JSONObject
archiveDate
=
iterator
.
next
();
if
(
0
==
archiveDate
.
optInt
(
ArchiveDate
.
ARCHIVE_DATE_PUBLISHED_ARTICLE_COUNT
))
{
if
(
0
==
archiveDate
.
optInt
(
ArchiveDate
.
ARCHIVE_DATE_PUBLISHED_ARTICLE_COUNT
))
{
iterator
.
remove
();
iterator
.
remove
();
}
}
}
}
}
}
/**
/**
* Gets the {@link ArchiveDateRepositoryImpl} singleton.
* Gets the {@link ArchiveDateRepositoryImpl} singleton.
*
*
* @return the singleton
* @return the singleton
*/
*/
public
static
ArchiveDateRepositoryImpl
getInstance
()
{
public
static
ArchiveDateRepositoryImpl
getInstance
()
{
return
SINGLETON
;
return
SINGLETON
;
}
}
/**
/**
* Private constructor.
* Private constructor.
*
*
* @param name the specified name
* @param name the specified name
*/
*/
private
ArchiveDateRepositoryImpl
(
final
String
name
)
{
private
ArchiveDateRepositoryImpl
(
final
String
name
)
{
super
(
name
);
super
(
name
);
}
}
}
}
core/src/main/java/org/b3log/solo/repository/impl/ArticleRepositoryImpl.java
View file @
65f8a5e9
/*
/*
* 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.1
D
;
private
static
final
double
RANDOM_RANGE
=
0.1
D
;
@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
().
addFilter
(
Article
.
ARTICLE_AUTHOR_EMAIL
,
FilterOperator
.
EQUAL
,
authorEmail
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
).
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
).
setCurrentPageNum
(
currentPageNum
).
setPageSize
(
pageSize
).
setPageCount
(
1
);
setCurrentPageNum
(
currentPageNum
).
setPageSize
(
pageSize
).
setPageCount
(
1
);
return
get
(
query
);
return
get
(
query
);
}
}
@Override
@Override
public
JSONObject
getByPermalink
(
final
String
permalink
)
throws
RepositoryException
{
public
JSONObject
getByPermalink
(
final
String
permalink
)
throws
RepositoryException
{
final
Query
query
=
new
Query
().
addFilter
(
Article
.
ARTICLE_PERMALINK
,
FilterOperator
.
EQUAL
,
permalink
).
final
Query
query
=
new
Query
().
addFilter
(
Article
.
ARTICLE_PERMALINK
,
FilterOperator
.
EQUAL
,
permalink
).
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
>
getRecentArticles
(
final
int
fetchSize
)
throws
RepositoryException
{
public
List
<
JSONObject
>
getRecentArticles
(
final
int
fetchSize
)
throws
RepositoryException
{
final
Query
query
=
new
Query
();
final
Query
query
=
new
Query
();
query
.
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
);
query
.
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
);
query
.
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
);
query
.
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
);
query
.
setCurrentPageNum
(
1
);
query
.
setCurrentPageNum
(
1
);
query
.
setPageSize
(
fetchSize
);
query
.
setPageSize
(
fetchSize
);
query
.
setPageCount
(
1
);
query
.
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
);
return
CollectionUtils
.
jsonArrayToList
(
array
);
return
CollectionUtils
.
jsonArrayToList
(
array
);
}
}
@Override
@Override
public
List
<
JSONObject
>
getMostCommentArticles
(
final
int
num
)
throws
RepositoryException
{
public
List
<
JSONObject
>
getMostCommentArticles
(
final
int
num
)
throws
RepositoryException
{
final
Query
query
=
new
Query
().
addSort
(
Article
.
ARTICLE_COMMENT_COUNT
,
SortDirection
.
DESCENDING
).
final
Query
query
=
new
Query
().
addSort
(
Article
.
ARTICLE_COMMENT_COUNT
,
SortDirection
.
DESCENDING
).
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
).
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
setCurrentPageNum
(
1
).
setPageSize
(
num
).
setPageCount
(
1
);
setCurrentPageNum
(
1
).
setPageSize
(
num
).
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
);
return
CollectionUtils
.
jsonArrayToList
(
array
);
return
CollectionUtils
.
jsonArrayToList
(
array
);
}
}
@Override
@Override
public
List
<
JSONObject
>
getMostViewCountArticles
(
final
int
num
)
throws
RepositoryException
{
public
List
<
JSONObject
>
getMostViewCountArticles
(
final
int
num
)
throws
RepositoryException
{
final
Query
query
=
new
Query
();
final
Query
query
=
new
Query
();
query
.
addSort
(
Article
.
ARTICLE_VIEW_COUNT
,
SortDirection
.
DESCENDING
).
query
.
addSort
(
Article
.
ARTICLE_VIEW_COUNT
,
SortDirection
.
DESCENDING
).
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
);
addSort
(
Article
.
ARTICLE_UPDATE_DATE
,
SortDirection
.
DESCENDING
);
query
.
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
);
query
.
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
);
query
.
setCurrentPageNum
(
1
);
query
.
setCurrentPageNum
(
1
);
query
.
setPageSize
(
num
);
query
.
setPageSize
(
num
);
query
.
setPageCount
(
1
);
query
.
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
);
return
CollectionUtils
.
jsonArrayToList
(
array
);
return
CollectionUtils
.
jsonArrayToList
(
array
);
}
}
@Override
@Override
public
JSONObject
getPreviousArticle
(
final
String
articleId
)
throws
RepositoryException
{
public
JSONObject
getPreviousArticle
(
final
String
articleId
)
throws
RepositoryException
{
final
JSONObject
currentArticle
=
get
(
articleId
);
final
JSONObject
currentArticle
=
get
(
articleId
);
final
Date
currentArticleCreateDate
=
(
Date
)
currentArticle
.
opt
(
Article
.
ARTICLE_CREATE_DATE
);
final
Date
currentArticleCreateDate
=
(
Date
)
currentArticle
.
opt
(
Article
.
ARTICLE_CREATE_DATE
);
final
Query
query
=
new
Query
().
addFilter
(
Article
.
ARTICLE_CREATE_DATE
,
FilterOperator
.
LESS_THAN
,
currentArticleCreateDate
).
final
Query
query
=
new
Query
().
addFilter
(
Article
.
ARTICLE_CREATE_DATE
,
FilterOperator
.
LESS_THAN
,
currentArticleCreateDate
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addSort
(
Article
.
ARTICLE_CREATE_DATE
,
SortDirection
.
DESCENDING
).
setCurrentPageNum
(
1
).
addSort
(
Article
.
ARTICLE_CREATE_DATE
,
SortDirection
.
DESCENDING
).
setCurrentPageNum
(
1
).
setPageSize
(
1
).
setPageCount
(
1
).
setPageSize
(
1
).
setPageCount
(
1
).
addProjection
(
Article
.
ARTICLE_TITLE
,
String
.
class
).
addProjection
(
Article
.
ARTICLE_TITLE
,
String
.
class
).
addProjection
(
Article
.
ARTICLE_PERMALINK
,
String
.
class
);
addProjection
(
Article
.
ARTICLE_PERMALINK
,
String
.
class
);
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
;
}
}
final
JSONObject
ret
=
new
JSONObject
();
final
JSONObject
ret
=
new
JSONObject
();
final
JSONObject
article
=
array
.
optJSONObject
(
0
);
final
JSONObject
article
=
array
.
optJSONObject
(
0
);
try
{
try
{
ret
.
put
(
Article
.
ARTICLE_TITLE
,
article
.
getString
(
Article
.
ARTICLE_TITLE
));
ret
.
put
(
Article
.
ARTICLE_TITLE
,
article
.
getString
(
Article
.
ARTICLE_TITLE
));
ret
.
put
(
Article
.
ARTICLE_PERMALINK
,
article
.
getString
(
Article
.
ARTICLE_PERMALINK
));
ret
.
put
(
Article
.
ARTICLE_PERMALINK
,
article
.
getString
(
Article
.
ARTICLE_PERMALINK
));
}
catch
(
final
JSONException
e
)
{
}
catch
(
final
JSONException
e
)
{
throw
new
RepositoryException
(
e
);
throw
new
RepositoryException
(
e
);
}
}
return
ret
;
return
ret
;
}
}
@Override
@Override
public
JSONObject
getNextArticle
(
final
String
articleId
)
throws
RepositoryException
{
public
JSONObject
getNextArticle
(
final
String
articleId
)
throws
RepositoryException
{
final
JSONObject
currentArticle
=
get
(
articleId
);
final
JSONObject
currentArticle
=
get
(
articleId
);
final
Date
currentArticleCreateDate
=
(
Date
)
currentArticle
.
opt
(
Article
.
ARTICLE_CREATE_DATE
);
final
Date
currentArticleCreateDate
=
(
Date
)
currentArticle
.
opt
(
Article
.
ARTICLE_CREATE_DATE
);
final
Query
query
=
new
Query
().
addFilter
(
Article
.
ARTICLE_CREATE_DATE
,
FilterOperator
.
GREATER_THAN
,
currentArticleCreateDate
).
final
Query
query
=
new
Query
().
addFilter
(
Article
.
ARTICLE_CREATE_DATE
,
FilterOperator
.
GREATER_THAN
,
currentArticleCreateDate
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
).
addSort
(
Article
.
ARTICLE_CREATE_DATE
,
SortDirection
.
ASCENDING
).
setCurrentPageNum
(
1
).
addSort
(
Article
.
ARTICLE_CREATE_DATE
,
SortDirection
.
ASCENDING
).
setCurrentPageNum
(
1
).
setPageSize
(
1
).
setPageCount
(
1
).
setPageSize
(
1
).
setPageCount
(
1
).
addProjection
(
Article
.
ARTICLE_TITLE
,
String
.
class
).
addProjection
(
Article
.
ARTICLE_TITLE
,
String
.
class
).
addProjection
(
Article
.
ARTICLE_PERMALINK
,
String
.
class
);
addProjection
(
Article
.
ARTICLE_PERMALINK
,
String
.
class
);
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
;
}
}
final
JSONObject
ret
=
new
JSONObject
();
final
JSONObject
ret
=
new
JSONObject
();
final
JSONObject
article
=
array
.
optJSONObject
(
0
);
final
JSONObject
article
=
array
.
optJSONObject
(
0
);
try
{
try
{
ret
.
put
(
Article
.
ARTICLE_TITLE
,
article
.
getString
(
Article
.
ARTICLE_TITLE
));
ret
.
put
(
Article
.
ARTICLE_TITLE
,
article
.
getString
(
Article
.
ARTICLE_TITLE
));
ret
.
put
(
Article
.
ARTICLE_PERMALINK
,
article
.
getString
(
Article
.
ARTICLE_PERMALINK
));
ret
.
put
(
Article
.
ARTICLE_PERMALINK
,
article
.
getString
(
Article
.
ARTICLE_PERMALINK
));
}
catch
(
final
JSONException
e
)
{
}
catch
(
final
JSONException
e
)
{
throw
new
RepositoryException
(
e
);
throw
new
RepositoryException
(
e
);
}
}
return
ret
;
return
ret
;
}
}
@Override
@Override
public
boolean
isPublished
(
final
String
articleId
)
throws
RepositoryException
{
public
boolean
isPublished
(
final
String
articleId
)
throws
RepositoryException
{
final
JSONObject
article
=
get
(
articleId
);
final
JSONObject
article
=
get
(
articleId
);
if
(
null
==
article
)
{
if
(
null
==
article
)
{
return
false
;
return
false
;
}
}
return
article
.
optBoolean
(
Article
.
ARTICLE_IS_PUBLISHED
);
return
article
.
optBoolean
(
Article
.
ARTICLE_IS_PUBLISHED
);
}
}
@Override
@Override
public
List
<
JSONObject
>
getRandomly
(
final
int
fetchSize
)
throws
RepositoryException
{
public
List
<
JSONObject
>
getRandomly
(
final
int
fetchSize
)
throws
RepositoryException
{
final
List
<
JSONObject
>
ret
=
new
ArrayList
<
JSONObject
>();
final
List
<
JSONObject
>
ret
=
new
ArrayList
<
JSONObject
>();
if
(
0
==
count
())
{
if
(
0
==
count
())
{
return
ret
;
return
ret
;
}
}
final
double
mid
=
Math
.
random
()
+
RANDOM_RANGE
;
final
double
mid
=
Math
.
random
()
+
RANDOM_RANGE
;
LOGGER
.
log
(
Level
.
FINEST
,
"Random mid[{0}]"
,
mid
);
LOGGER
.
log
(
Level
.
FINEST
,
"Random mid[{0}]"
,
mid
);
Query
query
=
new
Query
();
Query
query
=
new
Query
();
query
.
addFilter
(
Article
.
ARTICLE_RANDOM_DOUBLE
,
FilterOperator
.
GREATER_THAN_OR_EQUAL
,
mid
);
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_RANDOM_DOUBLE
,
FilterOperator
.
LESS_THAN_OR_EQUAL
,
mid
);
query
.
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
);
query
.
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
);
query
.
setCurrentPageNum
(
1
);
query
.
setCurrentPageNum
(
1
);
query
.
setPageSize
(
fetchSize
);
query
.
setPageSize
(
fetchSize
);
query
.
setPageCount
(
1
);
query
.
setPageCount
(
1
);
final
JSONObject
result1
=
get
(
query
);
final
JSONObject
result1
=
get
(
query
);
final
JSONArray
array1
=
result1
.
optJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
array1
=
result1
.
optJSONArray
(
Keys
.
RESULTS
);
final
List
<
JSONObject
>
list1
=
CollectionUtils
.<
JSONObject
>
jsonArrayToList
(
array1
);
final
List
<
JSONObject
>
list1
=
CollectionUtils
.<
JSONObject
>
jsonArrayToList
(
array1
);
ret
.
addAll
(
list1
);
ret
.
addAll
(
list1
);
final
int
reminingSize
=
fetchSize
-
array1
.
length
();
final
int
reminingSize
=
fetchSize
-
array1
.
length
();
if
(
0
!=
reminingSize
)
{
// Query for remains
if
(
0
!=
reminingSize
)
{
// Query for remains
query
=
new
Query
();
query
=
new
Query
();
query
.
addFilter
(
Article
.
ARTICLE_RANDOM_DOUBLE
,
FilterOperator
.
GREATER_THAN_OR_EQUAL
,
0
D
);
query
.
addFilter
(
Article
.
ARTICLE_RANDOM_DOUBLE
,
FilterOperator
.
GREATER_THAN_OR_EQUAL
,
0
D
);
query
.
addFilter
(
Article
.
ARTICLE_RANDOM_DOUBLE
,
FilterOperator
.
LESS_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
);
query
.
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
);
query
.
setCurrentPageNum
(
1
);
query
.
setCurrentPageNum
(
1
);
query
.
setPageSize
(
reminingSize
);
query
.
setPageSize
(
reminingSize
);
query
.
setPageCount
(
1
);
query
.
setPageCount
(
1
);
final
JSONObject
result2
=
get
(
query
);
final
JSONObject
result2
=
get
(
query
);
final
JSONArray
array2
=
result2
.
optJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
array2
=
result2
.
optJSONArray
(
Keys
.
RESULTS
);
final
List
<
JSONObject
>
list2
=
CollectionUtils
.<
JSONObject
>
jsonArrayToList
(
array2
);
final
List
<
JSONObject
>
list2
=
CollectionUtils
.<
JSONObject
>
jsonArrayToList
(
array2
);
ret
.
addAll
(
list2
);
ret
.
addAll
(
list2
);
}
}
return
ret
;
return
ret
;
}
}
/**
/**
* Gets the {@link ArticleRepositoryImpl} singleton.
* Gets the {@link ArticleRepositoryImpl} singleton.
*
*
* @return the singleton
* @return the singleton
*/
*/
public
static
ArticleRepositoryImpl
getInstance
()
{
public
static
ArticleRepositoryImpl
getInstance
()
{
return
SINGLETON
;
return
SINGLETON
;
}
}
/**
/**
* Private constructor.
* Private constructor.
*
*
* @param name the specified name
* @param name the specified name
*/
*/
private
ArticleRepositoryImpl
(
final
String
name
)
{
private
ArticleRepositoryImpl
(
final
String
name
)
{
super
(
name
);
super
(
name
);
}
}
}
}
core/src/main/java/org/b3log/solo/repository/impl/CommentRepositoryImpl.java
View file @
65f8a5e9
/*
/*
* 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.AbstractRepository
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.solo.model.Comment
;
import
org.b3log.solo.model.Comment
;
import
org.b3log.solo.repository.CommentRepository
;
import
org.b3log.solo.repository.CommentRepository
;
import
org.b3log.latke.util.CollectionUtils
;
import
org.b3log.latke.util.CollectionUtils
;
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.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
/**
/**
* Comment repository.
* Comment repository.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.8, Oct 18, 2011
* @version 1.0.0.8, Oct 18, 2011
* @since 0.3.1
* @since 0.3.1
*/
*/
public
final
class
CommentRepositoryImpl
extends
AbstractRepository
implements
CommentRepository
{
public
final
class
CommentRepositoryImpl
extends
AbstractRepository
implements
CommentRepository
{
/**
/**
* Logger.
* Logger.
*/
*/
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
CommentRepositoryImpl
.
class
.
getName
());
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
CommentRepositoryImpl
.
class
.
getName
());
/**
/**
* Singleton.
* Singleton.
*/
*/
private
static
final
CommentRepositoryImpl
SINGLETON
=
new
CommentRepositoryImpl
(
Comment
.
COMMENT
);
private
static
final
CommentRepositoryImpl
SINGLETON
=
new
CommentRepositoryImpl
(
Comment
.
COMMENT
);
/**
/**
* Article repository.
* Article repository.
*/
*/
private
ArticleRepository
articleRepository
=
ArticleRepositoryImpl
.
getInstance
();
private
ArticleRepository
articleRepository
=
ArticleRepositoryImpl
.
getInstance
();
/**
/**
* Recent comments query results cache key.
* Recent comments query results cache key.
*/
*/
public
static
final
String
RECENT_CMTS_CACHE_KEY
=
"recentCMTs"
;
public
static
final
String
RECENT_CMTS_CACHE_KEY
=
"recentCMTs"
;
@Override
@Override
public
int
removeComments
(
final
String
onId
)
throws
RepositoryException
{
public
int
removeComments
(
final
String
onId
)
throws
RepositoryException
{
final
List
<
JSONObject
>
comments
=
getComments
(
onId
,
1
,
Integer
.
MAX_VALUE
);
final
List
<
JSONObject
>
comments
=
getComments
(
onId
,
1
,
Integer
.
MAX_VALUE
);
for
(
final
JSONObject
comment
:
comments
)
{
for
(
final
JSONObject
comment
:
comments
)
{
final
String
commentId
=
comment
.
optString
(
Keys
.
OBJECT_ID
);
final
String
commentId
=
comment
.
optString
(
Keys
.
OBJECT_ID
);
remove
(
commentId
);
remove
(
commentId
);
}
}
LOGGER
.
log
(
Level
.
FINER
,
"Removed comments[onId={0}, removedCnt={1}]"
,
new
Object
[]{
onId
,
comments
.
size
()});
LOGGER
.
log
(
Level
.
FINER
,
"Removed comments[onId={0}, removedCnt={1}]"
,
new
Object
[]{
onId
,
comments
.
size
()});
return
comments
.
size
();
return
comments
.
size
();
}
}
@Override
@Override
public
List
<
JSONObject
>
getComments
(
final
String
onId
,
final
int
currentPageNum
,
final
int
pageSize
)
public
List
<
JSONObject
>
getComments
(
final
String
onId
,
final
int
currentPageNum
,
final
int
pageSize
)
throws
RepositoryException
{
throws
RepositoryException
{
final
Query
query
=
new
Query
().
addSort
(
Keys
.
OBJECT_ID
,
SortDirection
.
DESCENDING
).
final
Query
query
=
new
Query
().
addSort
(
Keys
.
OBJECT_ID
,
SortDirection
.
DESCENDING
).
addFilter
(
Comment
.
COMMENT_ON_ID
,
FilterOperator
.
EQUAL
,
onId
).
addFilter
(
Comment
.
COMMENT_ON_ID
,
FilterOperator
.
EQUAL
,
onId
).
setCurrentPageNum
(
currentPageNum
).
setCurrentPageNum
(
currentPageNum
).
setPageSize
(
pageSize
).
setPageSize
(
pageSize
).
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
);
return
CollectionUtils
.
jsonArrayToList
(
array
);
return
CollectionUtils
.
jsonArrayToList
(
array
);
}
}
@Override
@Override
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
public
List
<
JSONObject
>
getRecentComments
(
final
int
num
)
throws
RepositoryException
{
public
List
<
JSONObject
>
getRecentComments
(
final
int
num
)
throws
RepositoryException
{
if
(
isCacheEnabled
())
{
if
(
isCacheEnabled
())
{
final
Cache
<
String
,
Serializable
>
cache
=
getCache
();
final
Cache
<
String
,
Serializable
>
cache
=
getCache
();
final
Object
ret
=
cache
.
get
(
RECENT_CMTS_CACHE_KEY
);
final
Object
ret
=
cache
.
get
(
RECENT_CMTS_CACHE_KEY
);
if
(
null
!=
ret
)
{
if
(
null
!=
ret
)
{
return
(
List
<
JSONObject
>)
ret
;
return
(
List
<
JSONObject
>)
ret
;
}
}
}
}
final
Query
query
=
new
Query
().
addSort
(
Keys
.
OBJECT_ID
,
SortDirection
.
DESCENDING
).
final
Query
query
=
new
Query
().
addSort
(
Keys
.
OBJECT_ID
,
SortDirection
.
DESCENDING
).
setCurrentPageNum
(
1
).
setCurrentPageNum
(
1
).
setPageSize
(
num
).
setPageCount
(
1
);
setPageSize
(
num
).
setPageCount
(
1
);
List
<
JSONObject
>
ret
;
List
<
JSONObject
>
ret
;
final
JSONObject
result
=
get
(
query
);
final
JSONObject
result
=
get
(
query
);
final
JSONArray
array
=
result
.
optJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
array
=
result
.
optJSONArray
(
Keys
.
RESULTS
);
ret
=
CollectionUtils
.
jsonArrayToList
(
array
);
ret
=
CollectionUtils
.
jsonArrayToList
(
array
);
// Removes unpublished article related comments
// Removes unpublished article related comments
removeForUnpublishedArticles
(
ret
);
removeForUnpublishedArticles
(
ret
);
if
(
isCacheEnabled
())
{
if
(
isCacheEnabled
())
{
final
Cache
<
String
,
Serializable
>
cache
=
getCache
();
final
Cache
<
String
,
Serializable
>
cache
=
getCache
();
cache
.
put
(
RECENT_CMTS_CACHE_KEY
,
(
Serializable
)
ret
);
cache
.
put
(
RECENT_CMTS_CACHE_KEY
,
(
Serializable
)
ret
);
}
}
return
ret
;
return
ret
;
}
}
/**
/**
* Removes comments of unpublished articles for the specified comments.
* Removes comments of unpublished articles for the specified comments.
*
*
* @param comments the specified comments
* @param comments the specified comments
* @throws RepositoryException repository exception
* @throws RepositoryException repository exception
*/
*/
private
void
removeForUnpublishedArticles
(
final
List
<
JSONObject
>
comments
)
throws
RepositoryException
{
private
void
removeForUnpublishedArticles
(
final
List
<
JSONObject
>
comments
)
throws
RepositoryException
{
LOGGER
.
finer
(
"Removing unpublished articles' comments...."
);
LOGGER
.
finer
(
"Removing unpublished articles' comments...."
);
final
Iterator
<
JSONObject
>
iterator
=
comments
.
iterator
();
final
Iterator
<
JSONObject
>
iterator
=
comments
.
iterator
();
while
(
iterator
.
hasNext
())
{
while
(
iterator
.
hasNext
())
{
final
JSONObject
comment
=
iterator
.
next
();
final
JSONObject
comment
=
iterator
.
next
();
final
String
commentOnType
=
comment
.
optString
(
Comment
.
COMMENT_ON_TYPE
);
final
String
commentOnType
=
comment
.
optString
(
Comment
.
COMMENT_ON_TYPE
);
if
(
Article
.
ARTICLE
.
equals
(
commentOnType
))
{
if
(
Article
.
ARTICLE
.
equals
(
commentOnType
))
{
final
String
articleId
=
comment
.
optString
(
Comment
.
COMMENT_ON_ID
);
final
String
articleId
=
comment
.
optString
(
Comment
.
COMMENT_ON_ID
);
if
(!
articleRepository
.
isPublished
(
articleId
))
{
if
(!
articleRepository
.
isPublished
(
articleId
))
{
iterator
.
remove
();
iterator
.
remove
();
}
}
}
}
}
}
LOGGER
.
finer
(
"Removed unpublished articles' comments...."
);
LOGGER
.
finer
(
"Removed unpublished articles' comments...."
);
}
}
/**
/**
* Gets the {@link CommentRepositoryImpl} singleton.
* Gets the {@link CommentRepositoryImpl} singleton.
*
*
* @return the singleton
* @return the singleton
*/
*/
public
static
CommentRepositoryImpl
getInstance
()
{
public
static
CommentRepositoryImpl
getInstance
()
{
return
SINGLETON
;
return
SINGLETON
;
}
}
/**
/**
* Private constructor.
* Private constructor.
*
*
* @param name the specified name
* @param name the specified name
*/
*/
private
CommentRepositoryImpl
(
final
String
name
)
{
private
CommentRepositoryImpl
(
final
String
name
)
{
super
(
name
);
super
(
name
);
}
}
}
}
core/src/main/java/org/b3log/solo/repository/impl/LinkRepositoryImpl.java
View file @
65f8a5e9
/*
/*
* 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.AbstractRepository
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.solo.model.Link
;
import
org.b3log.solo.model.Link
;
import
org.b3log.solo.repository.LinkRepository
;
import
org.b3log.solo.repository.LinkRepository
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
/**
/**
* Link repository.
* Link repository.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.5, Nov 10, 2011
* @version 1.0.0.5, Nov 10, 2011
* @since 0.3.1
* @since 0.3.1
*/
*/
public
final
class
LinkRepositoryImpl
extends
AbstractRepository
implements
LinkRepository
{
public
final
class
LinkRepositoryImpl
extends
AbstractRepository
implements
LinkRepository
{
/**
/**
* Logger.
* Logger.
*/
*/
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
LinkRepositoryImpl
.
class
.
getName
());
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
LinkRepositoryImpl
.
class
.
getName
());
/**
/**
* Singleton.
* Singleton.
*/
*/
private
static
final
LinkRepositoryImpl
SINGLETON
=
new
LinkRepositoryImpl
(
Link
.
LINK
);
private
static
final
LinkRepositoryImpl
SINGLETON
=
new
LinkRepositoryImpl
(
Link
.
LINK
);
@Override
@Override
public
JSONObject
getByAddress
(
final
String
address
)
throws
RepositoryException
{
public
JSONObject
getByAddress
(
final
String
address
)
throws
RepositoryException
{
final
Query
query
=
new
Query
().
addFilter
(
Link
.
LINK_ADDRESS
,
FilterOperator
.
EQUAL
,
address
).
final
Query
query
=
new
Query
().
addFilter
(
Link
.
LINK_ADDRESS
,
FilterOperator
.
EQUAL
,
address
).
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
int
getMaxOrder
()
throws
RepositoryException
{
public
int
getMaxOrder
()
throws
RepositoryException
{
final
Query
query
=
new
Query
();
final
Query
query
=
new
Query
();
query
.
addSort
(
Link
.
LINK_ORDER
,
SortDirection
.
DESCENDING
);
query
.
addSort
(
Link
.
LINK_ORDER
,
SortDirection
.
DESCENDING
);
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
-
1
;
return
-
1
;
}
}
return
array
.
optJSONObject
(
0
).
optInt
(
Link
.
LINK_ORDER
);
return
array
.
optJSONObject
(
0
).
optInt
(
Link
.
LINK_ORDER
);
}
}
@Override
@Override
public
JSONObject
getByOrder
(
final
int
order
)
throws
RepositoryException
{
public
JSONObject
getByOrder
(
final
int
order
)
throws
RepositoryException
{
final
Query
query
=
new
Query
();
final
Query
query
=
new
Query
();
query
.
addFilter
(
Link
.
LINK_ORDER
,
FilterOperator
.
EQUAL
,
order
);
query
.
addFilter
(
Link
.
LINK_ORDER
,
FilterOperator
.
EQUAL
,
order
);
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
JSONObject
getUpper
(
final
String
id
)
throws
RepositoryException
{
public
JSONObject
getUpper
(
final
String
id
)
throws
RepositoryException
{
final
JSONObject
link
=
get
(
id
);
final
JSONObject
link
=
get
(
id
);
if
(
null
==
link
)
{
if
(
null
==
link
)
{
return
null
;
return
null
;
}
}
final
Query
query
=
new
Query
();
final
Query
query
=
new
Query
();
query
.
addFilter
(
Link
.
LINK_ORDER
,
FilterOperator
.
LESS_THAN
,
link
.
optInt
(
Link
.
LINK_ORDER
)).
query
.
addFilter
(
Link
.
LINK_ORDER
,
FilterOperator
.
LESS_THAN
,
link
.
optInt
(
Link
.
LINK_ORDER
)).
addSort
(
Link
.
LINK_ORDER
,
SortDirection
.
DESCENDING
);
addSort
(
Link
.
LINK_ORDER
,
SortDirection
.
DESCENDING
);
query
.
setCurrentPageNum
(
1
);
query
.
setCurrentPageNum
(
1
);
query
.
setPageSize
(
1
);
query
.
setPageSize
(
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
getUnder
(
final
String
id
)
throws
RepositoryException
{
public
JSONObject
getUnder
(
final
String
id
)
throws
RepositoryException
{
final
JSONObject
link
=
get
(
id
);
final
JSONObject
link
=
get
(
id
);
if
(
null
==
link
)
{
if
(
null
==
link
)
{
return
null
;
return
null
;
}
}
final
Query
query
=
new
Query
();
final
Query
query
=
new
Query
();
query
.
addFilter
(
Link
.
LINK_ORDER
,
FilterOperator
.
GREATER_THAN
,
link
.
optInt
(
Link
.
LINK_ORDER
)).
query
.
addFilter
(
Link
.
LINK_ORDER
,
FilterOperator
.
GREATER_THAN
,
link
.
optInt
(
Link
.
LINK_ORDER
)).
addSort
(
Link
.
LINK_ORDER
,
SortDirection
.
ASCENDING
);
addSort
(
Link
.
LINK_ORDER
,
SortDirection
.
ASCENDING
);
query
.
setCurrentPageNum
(
1
);
query
.
setCurrentPageNum
(
1
);
query
.
setPageSize
(
1
);
query
.
setPageSize
(
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
);
}
}
/**
/**
* Gets the {@link LinkRepositoryImpl} singleton.
* Gets the {@link LinkRepositoryImpl} singleton.
*
*
* @return the singleton
* @return the singleton
*/
*/
public
static
LinkRepositoryImpl
getInstance
()
{
public
static
LinkRepositoryImpl
getInstance
()
{
return
SINGLETON
;
return
SINGLETON
;
}
}
/**
/**
* Private constructor.
* Private constructor.
*
*
* @param name the specified name
* @param name the specified name
*/
*/
private
LinkRepositoryImpl
(
final
String
name
)
{
private
LinkRepositoryImpl
(
final
String
name
)
{
super
(
name
);
super
(
name
);
}
}
}
}
core/src/main/java/org/b3log/solo/repository/impl/PageRepositoryImpl.java
View file @
65f8a5e9
/*
/*
* 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.AbstractRepository
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.util.CollectionUtils
;
import
org.b3log.latke.util.CollectionUtils
;
import
org.b3log.solo.model.Page
;
import
org.b3log.solo.model.Page
;
import
org.b3log.solo.repository.PageRepository
;
import
org.b3log.solo.repository.PageRepository
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
/**
/**
* Page repository.
* Page repository.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.9, Dec 31, 2011
* @version 1.0.0.9, Dec 31, 2011
* @since 0.3.1
* @since 0.3.1
*/
*/
public
final
class
PageRepositoryImpl
extends
AbstractRepository
implements
PageRepository
{
public
final
class
PageRepositoryImpl
extends
AbstractRepository
implements
PageRepository
{
/**
/**
* Logger.
* Logger.
*/
*/
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
PageRepositoryImpl
.
class
.
getName
());
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
PageRepositoryImpl
.
class
.
getName
());
/**
/**
* Singleton.
* Singleton.
*/
*/
private
static
final
PageRepositoryImpl
SINGLETON
=
new
PageRepositoryImpl
(
Page
.
PAGE
);
private
static
final
PageRepositoryImpl
SINGLETON
=
new
PageRepositoryImpl
(
Page
.
PAGE
);
@Override
@Override
public
JSONObject
getByPermalink
(
final
String
permalink
)
throws
RepositoryException
{
public
JSONObject
getByPermalink
(
final
String
permalink
)
throws
RepositoryException
{
final
Query
query
=
new
Query
().
addFilter
(
Page
.
PAGE_PERMALINK
,
FilterOperator
.
EQUAL
,
permalink
).
final
Query
query
=
new
Query
().
addFilter
(
Page
.
PAGE_PERMALINK
,
FilterOperator
.
EQUAL
,
permalink
).
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
int
getMaxOrder
()
throws
RepositoryException
{
public
int
getMaxOrder
()
throws
RepositoryException
{
final
Query
query
=
new
Query
().
addSort
(
Page
.
PAGE_ORDER
,
SortDirection
.
DESCENDING
).
final
Query
query
=
new
Query
().
addSort
(
Page
.
PAGE_ORDER
,
SortDirection
.
DESCENDING
).
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
-
1
;
return
-
1
;
}
}
return
array
.
optJSONObject
(
0
).
optInt
(
Page
.
PAGE_ORDER
);
return
array
.
optJSONObject
(
0
).
optInt
(
Page
.
PAGE_ORDER
);
}
}
@Override
@Override
public
JSONObject
getUpper
(
final
String
id
)
throws
RepositoryException
{
public
JSONObject
getUpper
(
final
String
id
)
throws
RepositoryException
{
final
JSONObject
page
=
get
(
id
);
final
JSONObject
page
=
get
(
id
);
if
(
null
==
page
)
{
if
(
null
==
page
)
{
return
null
;
return
null
;
}
}
final
Query
query
=
new
Query
().
addFilter
(
Page
.
PAGE_ORDER
,
FilterOperator
.
LESS_THAN
,
page
.
optInt
(
Page
.
PAGE_ORDER
)).
final
Query
query
=
new
Query
().
addFilter
(
Page
.
PAGE_ORDER
,
FilterOperator
.
LESS_THAN
,
page
.
optInt
(
Page
.
PAGE_ORDER
)).
addSort
(
Page
.
PAGE_ORDER
,
SortDirection
.
DESCENDING
).
addSort
(
Page
.
PAGE_ORDER
,
SortDirection
.
DESCENDING
).
setCurrentPageNum
(
1
).
setPageSize
(
1
).
setPageCount
(
1
);
setCurrentPageNum
(
1
).
setPageSize
(
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
getUnder
(
final
String
id
)
throws
RepositoryException
{
public
JSONObject
getUnder
(
final
String
id
)
throws
RepositoryException
{
final
JSONObject
page
=
get
(
id
);
final
JSONObject
page
=
get
(
id
);
if
(
null
==
page
)
{
if
(
null
==
page
)
{
return
null
;
return
null
;
}
}
final
Query
query
=
new
Query
().
addFilter
(
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
().
addFilter
(
Page
.
PAGE_ORDER
,
FilterOperator
.
EQUAL
,
order
).
final
Query
query
=
new
Query
().
addFilter
(
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
);
}
}
}
}
core/src/main/java/org/b3log/solo/repository/impl/TagArticleRepositoryImpl.java
View file @
65f8a5e9
/*
/*
* 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.AbstractRepository
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.util.CollectionUtils
;
import
org.b3log.latke.util.CollectionUtils
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
/**
/**
* Tag-Article relation repository.
* Tag-Article relation repository.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.9, Nov 9, 2011
* @version 1.0.0.9, Nov 9, 2011
* @since 0.3.1
* @since 0.3.1
*/
*/
public
final
class
TagArticleRepositoryImpl
extends
AbstractRepository
implements
TagArticleRepository
{
public
final
class
TagArticleRepositoryImpl
extends
AbstractRepository
implements
TagArticleRepository
{
/**
/**
* Logger.
* Logger.
*/
*/
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
TagArticleRepositoryImpl
.
class
.
getName
());
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
TagArticleRepositoryImpl
.
class
.
getName
());
/**
/**
* Singleton.
* Singleton.
*/
*/
private
static
final
TagArticleRepositoryImpl
SINGLETON
=
new
TagArticleRepositoryImpl
(
Tag
.
TAG
+
"_"
+
Article
.
ARTICLE
);
private
static
final
TagArticleRepositoryImpl
SINGLETON
=
new
TagArticleRepositoryImpl
(
Tag
.
TAG
+
"_"
+
Article
.
ARTICLE
);
@Override
@Override
public
List
<
JSONObject
>
getByArticleId
(
final
String
articleId
)
throws
RepositoryException
{
public
List
<
JSONObject
>
getByArticleId
(
final
String
articleId
)
throws
RepositoryException
{
final
Query
query
=
new
Query
().
addFilter
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
,
FilterOperator
.
EQUAL
,
articleId
).
final
Query
query
=
new
Query
().
addFilter
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
,
FilterOperator
.
EQUAL
,
articleId
).
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
);
return
CollectionUtils
.
jsonArrayToList
(
array
);
return
CollectionUtils
.
jsonArrayToList
(
array
);
}
}
@Override
@Override
public
JSONObject
getByTagId
(
final
String
tagId
,
final
int
currentPageNum
,
final
int
pageSize
)
public
JSONObject
getByTagId
(
final
String
tagId
,
final
int
currentPageNum
,
final
int
pageSize
)
throws
RepositoryException
{
throws
RepositoryException
{
final
Query
query
=
new
Query
().
addFilter
(
Tag
.
TAG
+
"_"
+
Keys
.
OBJECT_ID
,
FilterOperator
.
EQUAL
,
tagId
).
final
Query
query
=
new
Query
().
addFilter
(
Tag
.
TAG
+
"_"
+
Keys
.
OBJECT_ID
,
FilterOperator
.
EQUAL
,
tagId
).
addSort
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
,
SortDirection
.
DESCENDING
).
addSort
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
,
SortDirection
.
DESCENDING
).
setCurrentPageNum
(
currentPageNum
).
setCurrentPageNum
(
currentPageNum
).
setPageSize
(
pageSize
).
setPageSize
(
pageSize
).
setPageCount
(
1
);
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
()
{
public
static
TagArticleRepositoryImpl
getInstance
()
{
return
SINGLETON
;
return
SINGLETON
;
}
}
/**
/**
* Private constructor.
* Private constructor.
*
*
* @param name the specified name
* @param name the specified name
*/
*/
private
TagArticleRepositoryImpl
(
final
String
name
)
{
private
TagArticleRepositoryImpl
(
final
String
name
)
{
super
(
name
);
super
(
name
);
}
}
}
}
core/src/main/java/org/b3log/solo/repository/impl/TagRepositoryImpl.java
View file @
65f8a5e9
/*
/*
* 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.AbstractRepository
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.util.CollectionUtils
;
import
org.b3log.latke.util.CollectionUtils
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
/**
/**
* Tag repository.
* Tag repository.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.1.1, Nov 29, 2011
* @version 1.0.1.1, Nov 29, 2011
* @since 0.3.1
* @since 0.3.1
*/
*/
public
final
class
TagRepositoryImpl
extends
AbstractRepository
implements
TagRepository
{
public
final
class
TagRepositoryImpl
extends
AbstractRepository
implements
TagRepository
{
/**
/**
* Logger.
* Logger.
*/
*/
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
TagRepositoryImpl
.
class
.
getName
());
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
TagRepositoryImpl
.
class
.
getName
());
/**
/**
* Singleton.
* Singleton.
*/
*/
private
static
final
TagRepositoryImpl
SINGLETON
=
new
TagRepositoryImpl
(
Tag
.
TAG
);
private
static
final
TagRepositoryImpl
SINGLETON
=
new
TagRepositoryImpl
(
Tag
.
TAG
);
/**
/**
* Tag-Article relation repository.
* Tag-Article relation repository.
*/
*/
private
TagArticleRepositoryImpl
tagArticleRepository
=
TagArticleRepositoryImpl
.
getInstance
();
private
TagArticleRepositoryImpl
tagArticleRepository
=
TagArticleRepositoryImpl
.
getInstance
();
@Override
@Override
public
JSONObject
getByTitle
(
final
String
tagTitle
)
throws
RepositoryException
{
public
JSONObject
getByTitle
(
final
String
tagTitle
)
throws
RepositoryException
{
final
Query
query
=
new
Query
().
addFilter
(
Tag
.
TAG_TITLE
,
FilterOperator
.
EQUAL
,
tagTitle
).
final
Query
query
=
new
Query
().
addFilter
(
Tag
.
TAG_TITLE
,
FilterOperator
.
EQUAL
,
tagTitle
).
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
>
getMostUsedTags
(
final
int
num
)
throws
RepositoryException
{
public
List
<
JSONObject
>
getMostUsedTags
(
final
int
num
)
throws
RepositoryException
{
final
Query
query
=
new
Query
().
addSort
(
Tag
.
TAG_PUBLISHED_REFERENCE_COUNT
,
SortDirection
.
DESCENDING
).
final
Query
query
=
new
Query
().
addSort
(
Tag
.
TAG_PUBLISHED_REFERENCE_COUNT
,
SortDirection
.
DESCENDING
).
setCurrentPageNum
(
1
).
setCurrentPageNum
(
1
).
setPageSize
(
num
).
setPageSize
(
num
).
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
);
return
CollectionUtils
.
jsonArrayToList
(
array
);
return
CollectionUtils
.
jsonArrayToList
(
array
);
}
}
@Override
@Override
public
List
<
JSONObject
>
getByArticleId
(
final
String
articleId
)
throws
RepositoryException
{
public
List
<
JSONObject
>
getByArticleId
(
final
String
articleId
)
throws
RepositoryException
{
final
List
<
JSONObject
>
ret
=
new
ArrayList
<
JSONObject
>();
final
List
<
JSONObject
>
ret
=
new
ArrayList
<
JSONObject
>();
final
List
<
JSONObject
>
tagArticleRelations
=
tagArticleRepository
.
getByArticleId
(
articleId
);
final
List
<
JSONObject
>
tagArticleRelations
=
tagArticleRepository
.
getByArticleId
(
articleId
);
for
(
final
JSONObject
tagArticleRelation
:
tagArticleRelations
)
{
for
(
final
JSONObject
tagArticleRelation
:
tagArticleRelations
)
{
final
String
tagId
=
tagArticleRelation
.
optString
(
Tag
.
TAG
+
"_"
+
Keys
.
OBJECT_ID
);
final
String
tagId
=
tagArticleRelation
.
optString
(
Tag
.
TAG
+
"_"
+
Keys
.
OBJECT_ID
);
final
JSONObject
tag
=
get
(
tagId
);
final
JSONObject
tag
=
get
(
tagId
);
ret
.
add
(
tag
);
ret
.
add
(
tag
);
}
}
return
ret
;
return
ret
;
}
}
/**
/**
* Gets the {@link TagRepositoryImpl} singleton.
* Gets the {@link TagRepositoryImpl} singleton.
*
*
* @return the singleton
* @return the singleton
*/
*/
public
static
TagRepositoryImpl
getInstance
()
{
public
static
TagRepositoryImpl
getInstance
()
{
return
SINGLETON
;
return
SINGLETON
;
}
}
/**
/**
* Private constructor.
* Private constructor.
*
*
* @param name the specified name
* @param name the specified name
*/
*/
private
TagRepositoryImpl
(
final
String
name
)
{
private
TagRepositoryImpl
(
final
String
name
)
{
super
(
name
);
super
(
name
);
}
}
}
}
core/src/main/java/org/b3log/solo/repository/impl/UserRepositoryImpl.java
View file @
65f8a5e9
/*
/*
* 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.AbstractRepository
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.FilterOperator
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.solo.repository.UserRepository
;
import
org.b3log.solo.repository.UserRepository
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
/**
/**
* User repository.
* User repository.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.8, Nov 10, 2011
* @version 1.0.0.8, Nov 10, 2011
* @since 0.3.1
* @since 0.3.1
*/
*/
public
final
class
UserRepositoryImpl
extends
AbstractRepository
implements
UserRepository
{
public
final
class
UserRepositoryImpl
extends
AbstractRepository
implements
UserRepository
{
/**
/**
* Logger.
* Logger.
*/
*/
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
UserRepositoryImpl
.
class
.
getName
());
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
UserRepositoryImpl
.
class
.
getName
());
/**
/**
* Singleton.
* Singleton.
*/
*/
private
static
final
UserRepositoryImpl
SINGLETON
=
new
UserRepositoryImpl
(
User
.
USER
);
private
static
final
UserRepositoryImpl
SINGLETON
=
new
UserRepositoryImpl
(
User
.
USER
);
@Override
@Override
public
JSONObject
getByEmail
(
final
String
email
)
throws
RepositoryException
{
public
JSONObject
getByEmail
(
final
String
email
)
throws
RepositoryException
{
final
Query
query
=
new
Query
().
setPageCount
(
1
);
final
Query
query
=
new
Query
().
setPageCount
(
1
);
query
.
addFilter
(
User
.
USER_EMAIL
,
FilterOperator
.
EQUAL
,
email
.
toLowerCase
().
trim
());
query
.
addFilter
(
User
.
USER_EMAIL
,
FilterOperator
.
EQUAL
,
email
.
toLowerCase
().
trim
());
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
JSONObject
getAdmin
()
throws
RepositoryException
{
public
JSONObject
getAdmin
()
throws
RepositoryException
{
final
Query
query
=
new
Query
().
addFilter
(
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
);
}
}
}
}
core/src/main/java/org/b3log/solo/service/ArticleQueryService.java
View file @
65f8a5e9
/*
/*
* 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.RepositoryException
;
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
);
addFilter
(
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
articleIsPublished
);
int
articleCount
=
statistics
.
getBlogArticleCount
();
int
articleCount
=
statistics
.
getBlogArticleCount
();
if
(!
articleIsPublished
)
{
if
(!
articleIsPublished
)
{
articleCount
-=
statistics
.
getPublishedBlogArticleCount
();
articleCount
-=
statistics
.
getPublishedBlogArticleCount
();
}
}
final
int
pageCount
=
(
int
)
Math
.
ceil
((
double
)
articleCount
/
(
double
)
pageSize
);
final
int
pageCount
=
(
int
)
Math
.
ceil
((
double
)
articleCount
/
(
double
)
pageSize
);
query
.
setPageCount
(
pageCount
);
query
.
setPageCount
(
pageCount
);
final
JSONObject
result
=
articleRepository
.
get
(
query
);
final
JSONObject
result
=
articleRepository
.
get
(
query
);
final
JSONObject
pagination
=
new
JSONObject
();
final
JSONObject
pagination
=
new
JSONObject
();
ret
.
put
(
Pagination
.
PAGINATION
,
pagination
);
ret
.
put
(
Pagination
.
PAGINATION
,
pagination
);
final
List
<
Integer
>
pageNums
=
Paginator
.
paginate
(
currentPageNum
,
pageSize
,
pageCount
,
windowSize
);
final
List
<
Integer
>
pageNums
=
Paginator
.
paginate
(
currentPageNum
,
pageSize
,
pageCount
,
windowSize
);
pagination
.
put
(
Pagination
.
PAGINATION_PAGE_COUNT
,
pageCount
);
pagination
.
put
(
Pagination
.
PAGINATION_PAGE_COUNT
,
pageCount
);
pagination
.
put
(
Pagination
.
PAGINATION_PAGE_NUMS
,
pageNums
);
pagination
.
put
(
Pagination
.
PAGINATION_PAGE_NUMS
,
pageNums
);
final
JSONArray
articles
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
articles
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
JSONArray
excludes
=
requestJSONObject
.
optJSONArray
(
Keys
.
EXCLUDES
);
JSONArray
excludes
=
requestJSONObject
.
optJSONArray
(
Keys
.
EXCLUDES
);
excludes
=
null
==
excludes
?
new
JSONArray
()
:
excludes
;
excludes
=
null
==
excludes
?
new
JSONArray
()
:
excludes
;
for
(
int
i
=
0
;
i
<
articles
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
articles
.
length
();
i
++)
{
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
final
JSONObject
author
=
articleUtils
.
getAuthor
(
article
);
final
JSONObject
author
=
articleUtils
.
getAuthor
(
article
);
final
String
authorName
=
author
.
getString
(
User
.
USER_NAME
);
final
String
authorName
=
author
.
getString
(
User
.
USER_NAME
);
article
.
put
(
Common
.
AUTHOR_NAME
,
authorName
);
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 to HTML for content and abstract
markdown
(
article
);
markdown
(
article
);
// Remove unused properties
// Remove unused properties
for
(
int
j
=
0
;
j
<
excludes
.
length
();
j
++)
{
for
(
int
j
=
0
;
j
<
excludes
.
length
();
j
++)
{
article
.
remove
(
excludes
.
optString
(
j
));
article
.
remove
(
excludes
.
optString
(
j
));
}
}
}
}
ret
.
put
(
ARTICLES
,
articles
);
ret
.
put
(
ARTICLES
,
articles
);
return
ret
;
return
ret
;
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets articles failed"
,
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 tagId the specified tag id
* @param currentPageNum the specified current page number
* @param currentPageNum the specified current page number
* @param pageSize the specified page size
* @param pageSize the specified page size
* @return a list of articles, returns an empty list if not found
* @return a list of articles, returns an empty list if not found
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
List
<
JSONObject
>
getArticlesByTag
(
final
String
tagId
,
final
int
currentPageNum
,
final
int
pageSize
)
public
List
<
JSONObject
>
getArticlesByTag
(
final
String
tagId
,
final
int
currentPageNum
,
final
int
pageSize
)
throws
ServiceException
{
throws
ServiceException
{
try
{
try
{
JSONObject
result
=
tagArticleRepository
.
getByTagId
(
tagId
,
currentPageNum
,
pageSize
);
JSONObject
result
=
tagArticleRepository
.
getByTagId
(
tagId
,
currentPageNum
,
pageSize
);
final
JSONArray
tagArticleRelations
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
tagArticleRelations
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
if
(
0
==
tagArticleRelations
.
length
())
{
if
(
0
==
tagArticleRelations
.
length
())
{
return
Collections
.
emptyList
();
return
Collections
.
emptyList
();
}
}
final
Set
<
String
>
articleIds
=
new
HashSet
<
String
>();
final
Set
<
String
>
articleIds
=
new
HashSet
<
String
>();
for
(
int
i
=
0
;
i
<
tagArticleRelations
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
tagArticleRelations
.
length
();
i
++)
{
final
JSONObject
tagArticleRelation
=
tagArticleRelations
.
getJSONObject
(
i
);
final
JSONObject
tagArticleRelation
=
tagArticleRelations
.
getJSONObject
(
i
);
final
String
articleId
=
tagArticleRelation
.
getString
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
);
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
).
final
Query
query
=
new
Query
().
addFilter
(
Keys
.
OBJECT_ID
,
FilterOperator
.
IN
,
articleIds
).
setPageCount
(
1
).
index
(
Article
.
ARTICLE_PERMALINK
);
setPageCount
(
1
).
index
(
Article
.
ARTICLE_PERMALINK
);
result
=
articleRepository
.
get
(
query
);
result
=
articleRepository
.
get
(
query
);
final
JSONArray
articles
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
articles
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
for
(
int
i
=
0
;
i
<
articles
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
articles
.
length
();
i
++)
{
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
if
(!
article
.
getBoolean
(
Article
.
ARTICLE_IS_PUBLISHED
))
{
if
(!
article
.
getBoolean
(
Article
.
ARTICLE_IS_PUBLISHED
))
{
// Skips the unpublished article
// Skips the unpublished article
continue
;
continue
;
}
}
// Markdown to HTML for content and abstract
// Markdown to HTML for content and abstract
markdown
(
article
);
markdown
(
article
);
ret
.
add
(
article
);
ret
.
add
(
article
);
}
}
return
ret
;
return
ret
;
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets articles by tag[id="
+
tagId
+
"] failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets articles by tag[id="
+
tagId
+
"] failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
}
}
}
/**
/**
* Gets a list of published articles with the specified archive date id, current page number and page size.
* 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
* @param archiveDateId the specified archive date id
* @param currentPageNum the specified current page number
* @param currentPageNum the specified current page number
* @param pageSize the specified page size
* @param pageSize the specified page size
* @return a list of articles, returns an empty list if not found
* @return a list of articles, returns an empty list if not found
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
List
<
JSONObject
>
getArticlesByArchiveDate
(
final
String
archiveDateId
,
final
int
currentPageNum
,
final
int
pageSize
)
public
List
<
JSONObject
>
getArticlesByArchiveDate
(
final
String
archiveDateId
,
final
int
currentPageNum
,
final
int
pageSize
)
throws
ServiceException
{
throws
ServiceException
{
try
{
try
{
JSONObject
result
=
archiveDateArticleRepository
.
getByArchiveDateId
(
archiveDateId
,
currentPageNum
,
pageSize
);
JSONObject
result
=
archiveDateArticleRepository
.
getByArchiveDateId
(
archiveDateId
,
currentPageNum
,
pageSize
);
final
JSONArray
relations
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
relations
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
if
(
0
==
relations
.
length
())
{
if
(
0
==
relations
.
length
())
{
return
Collections
.
emptyList
();
return
Collections
.
emptyList
();
}
}
final
Set
<
String
>
articleIds
=
new
HashSet
<
String
>();
final
Set
<
String
>
articleIds
=
new
HashSet
<
String
>();
for
(
int
i
=
0
;
i
<
relations
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
relations
.
length
();
i
++)
{
final
JSONObject
relation
=
relations
.
getJSONObject
(
i
);
final
JSONObject
relation
=
relations
.
getJSONObject
(
i
);
final
String
articleId
=
relation
.
getString
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
);
final
String
articleId
=
relation
.
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
).
final
Query
query
=
new
Query
().
addFilter
(
Keys
.
OBJECT_ID
,
FilterOperator
.
IN
,
articleIds
).
setPageCount
(
1
).
index
(
Article
.
ARTICLE_PERMALINK
);
setPageCount
(
1
).
index
(
Article
.
ARTICLE_PERMALINK
);
result
=
articleRepository
.
get
(
query
);
result
=
articleRepository
.
get
(
query
);
final
JSONArray
articles
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
articles
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
for
(
int
i
=
0
;
i
<
articles
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
articles
.
length
();
i
++)
{
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
if
(!
article
.
getBoolean
(
Article
.
ARTICLE_IS_PUBLISHED
))
{
if
(!
article
.
getBoolean
(
Article
.
ARTICLE_IS_PUBLISHED
))
{
// Skips the unpublished article
// Skips the unpublished article
continue
;
continue
;
}
}
// Markdown to HTML for content and abstract
// Markdown to HTML for content and abstract
markdown
(
article
);
markdown
(
article
);
ret
.
add
(
article
);
ret
.
add
(
article
);
}
}
return
ret
;
return
ret
;
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets articles by archive date[id="
+
archiveDateId
+
"] failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets articles by archive date[id="
+
archiveDateId
+
"] failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
}
}
}
/**
/**
* Gets a list of articles randomly with the specified fetch size.
* Gets a list of articles randomly with the specified fetch size.
*
*
* <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 fetchSize the specified fetch size
* @param fetchSize the specified fetch size
* @return a list of json objects, its size less or equal to the specified
* @return a list of json objects, its size less or equal to the specified
* fetch size
* fetch size
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
List
<
JSONObject
>
getArticlesRandomly
(
final
int
fetchSize
)
throws
ServiceException
{
public
List
<
JSONObject
>
getArticlesRandomly
(
final
int
fetchSize
)
throws
ServiceException
{
try
{
try
{
final
List
<
JSONObject
>
ret
=
articleRepository
.
getRandomly
(
fetchSize
);
final
List
<
JSONObject
>
ret
=
articleRepository
.
getRandomly
(
fetchSize
);
removeUnusedProperties
(
ret
);
removeUnusedProperties
(
ret
);
return
ret
;
return
ret
;
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets articles randomly failed[fetchSize="
+
fetchSize
+
"]"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets articles randomly failed[fetchSize="
+
fetchSize
+
"]"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
}
}
}
/**
/**
* Gets the relevant published articles of the specified article.
* Gets the relevant published articles of the specified article.
*
*
* <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 article the specified article
* @param article the specified article
* @param preference the specified preference
* @param preference the specified preference
* @return a list of articles, returns an empty list if not found
* @return a list of articles, returns an empty list if not found
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
List
<
JSONObject
>
getRelevantArticles
(
final
JSONObject
article
,
final
JSONObject
preference
)
public
List
<
JSONObject
>
getRelevantArticles
(
final
JSONObject
article
,
final
JSONObject
preference
)
throws
ServiceException
{
throws
ServiceException
{
try
{
try
{
final
int
displayCnt
=
preference
.
getInt
(
Preference
.
RELEVANT_ARTICLES_DISPLAY_CNT
);
final
int
displayCnt
=
preference
.
getInt
(
Preference
.
RELEVANT_ARTICLES_DISPLAY_CNT
);
final
String
[]
tagTitles
=
article
.
getString
(
Article
.
ARTICLE_TAGS_REF
).
split
(
","
);
final
String
[]
tagTitles
=
article
.
getString
(
Article
.
ARTICLE_TAGS_REF
).
split
(
","
);
final
int
maxTagCnt
=
displayCnt
>
tagTitles
.
length
?
tagTitles
.
length
:
displayCnt
;
final
int
maxTagCnt
=
displayCnt
>
tagTitles
.
length
?
tagTitles
.
length
:
displayCnt
;
final
String
articleId
=
article
.
getString
(
Keys
.
OBJECT_ID
);
final
String
articleId
=
article
.
getString
(
Keys
.
OBJECT_ID
);
final
List
<
JSONObject
>
articles
=
new
ArrayList
<
JSONObject
>();
final
List
<
JSONObject
>
articles
=
new
ArrayList
<
JSONObject
>();
for
(
int
i
=
0
;
i
<
maxTagCnt
;
i
++)
{
// XXX: should average by tag?
for
(
int
i
=
0
;
i
<
maxTagCnt
;
i
++)
{
// XXX: should average by tag?
final
String
tagTitle
=
tagTitles
[
i
];
final
String
tagTitle
=
tagTitles
[
i
];
final
JSONObject
tag
=
tagRepository
.
getByTitle
(
tagTitle
);
final
JSONObject
tag
=
tagRepository
.
getByTitle
(
tagTitle
);
final
String
tagId
=
tag
.
getString
(
Keys
.
OBJECT_ID
);
final
String
tagId
=
tag
.
getString
(
Keys
.
OBJECT_ID
);
final
JSONObject
result
=
tagArticleRepository
.
getByTagId
(
tagId
,
1
,
displayCnt
);
final
JSONObject
result
=
tagArticleRepository
.
getByTagId
(
tagId
,
1
,
displayCnt
);
final
JSONArray
tagArticleRelations
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
tagArticleRelations
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
int
relationSize
=
displayCnt
<
tagArticleRelations
.
length
()
?
displayCnt
:
tagArticleRelations
.
length
();
final
int
relationSize
=
displayCnt
<
tagArticleRelations
.
length
()
?
displayCnt
:
tagArticleRelations
.
length
();
for
(
int
j
=
0
;
j
<
relationSize
;
j
++)
{
for
(
int
j
=
0
;
j
<
relationSize
;
j
++)
{
final
JSONObject
tagArticleRelation
=
tagArticleRelations
.
getJSONObject
(
j
);
final
JSONObject
tagArticleRelation
=
tagArticleRelations
.
getJSONObject
(
j
);
final
String
relatedArticleId
=
tagArticleRelation
.
getString
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
);
final
String
relatedArticleId
=
tagArticleRelation
.
getString
(
Article
.
ARTICLE
+
"_"
+
Keys
.
OBJECT_ID
);
if
(
articleId
.
equals
(
relatedArticleId
))
{
if
(
articleId
.
equals
(
relatedArticleId
))
{
continue
;
continue
;
}
}
final
JSONObject
relevant
=
articleRepository
.
get
(
relatedArticleId
);
final
JSONObject
relevant
=
articleRepository
.
get
(
relatedArticleId
);
if
(!
relevant
.
getBoolean
(
Article
.
ARTICLE_IS_PUBLISHED
))
{
if
(!
relevant
.
getBoolean
(
Article
.
ARTICLE_IS_PUBLISHED
))
{
continue
;
continue
;
}
}
boolean
existed
=
false
;
boolean
existed
=
false
;
for
(
final
JSONObject
relevantArticle
:
articles
)
{
for
(
final
JSONObject
relevantArticle
:
articles
)
{
if
(
relevantArticle
.
getString
(
Keys
.
OBJECT_ID
).
if
(
relevantArticle
.
getString
(
Keys
.
OBJECT_ID
).
equals
(
relevant
.
getString
(
Keys
.
OBJECT_ID
)))
{
equals
(
relevant
.
getString
(
Keys
.
OBJECT_ID
)))
{
existed
=
true
;
existed
=
true
;
}
}
}
}
if
(!
existed
)
{
if
(!
existed
)
{
articles
.
add
(
relevant
);
articles
.
add
(
relevant
);
}
}
}
}
}
}
Collections
.
sort
(
articles
,
Comparators
.
ARTICLE_UPDATE_DATE_COMPARATOR
);
Collections
.
sort
(
articles
,
Comparators
.
ARTICLE_UPDATE_DATE_COMPARATOR
);
removeUnusedProperties
(
articles
);
removeUnusedProperties
(
articles
);
if
(
displayCnt
>
articles
.
size
())
{
if
(
displayCnt
>
articles
.
size
())
{
return
articles
;
return
articles
;
}
}
final
List
<
Integer
>
randomIntegers
=
CollectionUtils
.
getRandomIntegers
(
0
,
articles
.
size
()
-
1
,
displayCnt
);
final
List
<
Integer
>
randomIntegers
=
CollectionUtils
.
getRandomIntegers
(
0
,
articles
.
size
()
-
1
,
displayCnt
);
final
List
<
JSONObject
>
ret
=
new
ArrayList
<
JSONObject
>();
final
List
<
JSONObject
>
ret
=
new
ArrayList
<
JSONObject
>();
for
(
final
int
index
:
randomIntegers
)
{
for
(
final
int
index
:
randomIntegers
)
{
ret
.
add
(
articles
.
get
(
index
));
ret
.
add
(
articles
.
get
(
index
));
}
}
return
ret
;
return
ret
;
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets relevant articles failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets relevant articles failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
}
}
}
/**
/**
* Determines an article specified by the given article id is published.
* Determines an article specified by the given article id is published.
*
*
* @param articleId the given article id
* @param articleId the given article id
* @return {@code true} if it is published
* @return {@code true} if it is published
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
boolean
isArticlePublished
(
final
String
articleId
)
throws
ServiceException
{
public
boolean
isArticlePublished
(
final
String
articleId
)
throws
ServiceException
{
try
{
try
{
return
articleRepository
.
isPublished
(
articleId
);
return
articleRepository
.
isPublished
(
articleId
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Determines the article publish status failed[articleId="
+
articleId
+
"]"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Determines the article publish status failed[articleId="
+
articleId
+
"]"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
}
}
}
/**
/**
* Gets the next article(by create date) by the specified article id.
* Gets the next article(by create date) 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 the previous article,
* @return the previous article,
* <pre>
* <pre>
* {
* {
* "articleTitle": "",
* "articleTitle": "",
* "articlePermalink": ""
* "articlePermalink": ""
* }
* }
* </pre>
* </pre>
* returns {@code null} if not found
* returns {@code null} if not found
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
JSONObject
getNextArticle
(
final
String
articleId
)
throws
ServiceException
{
public
JSONObject
getNextArticle
(
final
String
articleId
)
throws
ServiceException
{
try
{
try
{
return
articleRepository
.
getNextArticle
(
articleId
);
return
articleRepository
.
getNextArticle
(
articleId
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets the next article failed[articleId="
+
articleId
+
"]"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets the next article failed[articleId="
+
articleId
+
"]"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
}
}
}
/**
/**
* Gets the previous article(by create date) by the specified article id.
* Gets the previous article(by create date) 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 the previous article,
* @return the previous article,
* <pre>
* <pre>
* {
* {
* "articleTitle": "",
* "articleTitle": "",
* "articlePermalink": ""
* "articlePermalink": ""
* }
* }
* </pre>
* </pre>
* returns {@code null} if not found
* returns {@code null} if not found
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
JSONObject
getPreviousArticle
(
final
String
articleId
)
throws
ServiceException
{
public
JSONObject
getPreviousArticle
(
final
String
articleId
)
throws
ServiceException
{
try
{
try
{
return
articleRepository
.
getPreviousArticle
(
articleId
);
return
articleRepository
.
getPreviousArticle
(
articleId
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets the previous article failed[articleId="
+
articleId
+
"]"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets the previous article failed[articleId="
+
articleId
+
"]"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
}
}
}
/**
/**
* 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 an article, returns {@code null} if not found
* @return an article, returns {@code null} if not found
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
JSONObject
getArticleById
(
final
String
articleId
)
throws
ServiceException
{
public
JSONObject
getArticleById
(
final
String
articleId
)
throws
ServiceException
{
try
{
try
{
return
articleRepository
.
get
(
articleId
);
return
articleRepository
.
get
(
articleId
);
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets an article[articleId="
+
articleId
+
"] failed"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets an article[articleId="
+
articleId
+
"] failed"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
}
}
}
/**
/**
* Gets <em>published</em> articles by the specified author email, current page number and page size.
* Gets <em>published</em> articles by the specified author email, current page number and page size.
*
*
* @param authorEmail the specified author email
* @param authorEmail the specified author email
* @param currentPageNum the specified current page number
* @param currentPageNum the specified current page number
* @param pageSize the specified page size
* @param pageSize the specified page size
* @return a list of articles, returns an empty list if not found
* @return a list of articles, returns an empty list if not found
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
List
<
JSONObject
>
getArticlesByAuthorEmail
(
final
String
authorEmail
,
final
int
currentPageNum
,
final
int
pageSize
)
public
List
<
JSONObject
>
getArticlesByAuthorEmail
(
final
String
authorEmail
,
final
int
currentPageNum
,
final
int
pageSize
)
throws
ServiceException
{
throws
ServiceException
{
try
{
try
{
final
JSONObject
result
=
articleRepository
.
getByAuthorEmail
(
authorEmail
,
currentPageNum
,
pageSize
);
final
JSONObject
result
=
articleRepository
.
getByAuthorEmail
(
authorEmail
,
currentPageNum
,
pageSize
);
final
JSONArray
articles
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
JSONArray
articles
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
final
List
<
JSONObject
>
ret
=
new
ArrayList
<
JSONObject
>();
final
List
<
JSONObject
>
ret
=
new
ArrayList
<
JSONObject
>();
for
(
int
i
=
0
;
i
<
articles
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
articles
.
length
();
i
++)
{
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
final
JSONObject
article
=
articles
.
getJSONObject
(
i
);
// Markdown to HTML for content and abstract
// Markdown to HTML for content and abstract
markdown
(
article
);
markdown
(
article
);
ret
.
add
(
article
);
ret
.
add
(
article
);
}
}
return
ret
;
return
ret
;
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets articles by author email failed[authorEmail="
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets articles by author email failed[authorEmail="
+
authorEmail
+
", currentPageNum="
+
currentPageNum
+
", pageSize="
+
pageSize
+
"]"
,
e
);
+
authorEmail
+
", currentPageNum="
+
currentPageNum
+
", pageSize="
+
pageSize
+
"]"
,
e
);
throw
new
ServiceException
(
e
);
throw
new
ServiceException
(
e
);
}
}
}
}
/**
/**
* Gets article contents with the specified article id.
* Gets article contents with the specified article id.
*
*
* <p>
* <p>
* Invoking this method dose not effect on article view count.
* Invoking this method dose not effect on article view count.
* </p>
* </p>
*
*
* @param articleId the specified article id
* @param articleId the specified article id
* @return article contents, returns {@code null} if not found
* @return article contents, returns {@code null} if not found
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
String
getArticleContent
(
final
String
articleId
)
throws
ServiceException
{
public
String
getArticleContent
(
final
String
articleId
)
throws
ServiceException
{
if
(
Strings
.
isEmptyOrNull
(
articleId
))
{
if
(
Strings
.
isEmptyOrNull
(
articleId
))
{
return
null
;
return
null
;
}
}
try
{
try
{
final
JSONObject
article
=
articleRepository
.
get
(
articleId
);
final
JSONObject
article
=
articleRepository
.
get
(
articleId
);
if
(
null
==
article
)
{
if
(
null
==
article
)
{
return
null
;
return
null
;
}
}
// Markdown to HTML for content and abstract
// Markdown to HTML for content and abstract
if
(
"CodeMirror-Markdown"
.
equals
(
article
.
optString
(
ARTICLE_EDITOR_TYPE
)))
{
if
(
"CodeMirror-Markdown"
.
equals
(
article
.
optString
(
ARTICLE_EDITOR_TYPE
)))
{
Stopwatchs
.
start
(
"Get Article Content [Markdown]"
);
Stopwatchs
.
start
(
"Get Article Content [Markdown]"
);
final
String
content
=
article
.
optString
(
ARTICLE_CONTENT
);
final
String
content
=
article
.
optString
(
ARTICLE_CONTENT
);
article
.
put
(
ARTICLE_CONTENT
,
Markdowns
.
toHTML
(
content
));
article
.
put
(
ARTICLE_CONTENT
,
Markdowns
.
toHTML
(
content
));
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
return
article
.
getString
(
Article
.
ARTICLE_CONTENT
);
return
article
.
getString
(
Article
.
ARTICLE_CONTENT
);
}
catch
(
final
Exception
e
)
{
}
catch
(
final
Exception
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets article content failed[articleId="
+
articleId
+
"]"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Gets article content failed[articleId="
+
articleId
+
"]"
,
e
);
throw
new
ServiceException
(
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.
* 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
* @param articles the specified articles
* @throws Exception exception
* @throws Exception exception
*/
*/
public
void
markdowns
(
final
List
<
JSONObject
>
articles
)
throws
Exception
{
public
void
markdowns
(
final
List
<
JSONObject
>
articles
)
throws
Exception
{
for
(
final
JSONObject
article
:
articles
)
{
for
(
final
JSONObject
article
:
articles
)
{
markdown
(
article
);
markdown
(
article
);
}
}
}
}
/**
/**
* Converts the content and abstract for the specified article to HTML if it is saved by Markdown editor.
* Converts the content and abstract for the specified article to HTML if it is saved by Markdown editor.
*
*
* @param article the specified article
* @param article the specified article
* @throws Exception exception
* @throws Exception exception
*/
*/
public
void
markdown
(
final
JSONObject
article
)
throws
Exception
{
public
void
markdown
(
final
JSONObject
article
)
throws
Exception
{
if
(
"CodeMirror-Markdown"
.
equals
(
article
.
optString
(
ARTICLE_EDITOR_TYPE
)))
{
if
(
"CodeMirror-Markdown"
.
equals
(
article
.
optString
(
ARTICLE_EDITOR_TYPE
)))
{
Stopwatchs
.
start
(
"Markdown Article[id="
+
article
.
optString
(
Keys
.
OBJECT_ID
)
+
"]"
);
Stopwatchs
.
start
(
"Markdown Article[id="
+
article
.
optString
(
Keys
.
OBJECT_ID
)
+
"]"
);
Stopwatchs
.
start
(
"Content"
);
Stopwatchs
.
start
(
"Content"
);
final
String
content
=
article
.
optString
(
ARTICLE_CONTENT
);
final
String
content
=
article
.
optString
(
ARTICLE_CONTENT
);
article
.
put
(
ARTICLE_CONTENT
,
Markdowns
.
toHTML
(
content
));
article
.
put
(
ARTICLE_CONTENT
,
Markdowns
.
toHTML
(
content
));
Stopwatchs
.
end
();
Stopwatchs
.
end
();
final
String
abstractContent
=
article
.
optString
(
ARTICLE_ABSTRACT
);
final
String
abstractContent
=
article
.
optString
(
ARTICLE_ABSTRACT
);
if
(!
Strings
.
isEmptyOrNull
(
abstractContent
))
{
if
(!
Strings
.
isEmptyOrNull
(
abstractContent
))
{
Stopwatchs
.
start
(
"Abstract"
);
Stopwatchs
.
start
(
"Abstract"
);
article
.
put
(
ARTICLE_ABSTRACT
,
Markdowns
.
toHTML
(
abstractContent
));
article
.
put
(
ARTICLE_ABSTRACT
,
Markdowns
.
toHTML
(
abstractContent
));
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
Stopwatchs
.
end
();
Stopwatchs
.
end
();
}
}
}
}
/**
/**
* Removes unused properties of each article in the specified articles.
* Removes unused properties of each article in the specified articles.
*
*
* <p>
* <p>
* Remains the following properties:
* Remains the following properties:
* <ul>
* <ul>
* <li>{@link Article#ARTICLE_TITLE article title}</li>
* <li>{@link Article#ARTICLE_TITLE article title}</li>
* <li>{@link Article#ARTICLE_PERMALINK article permalink}</li>
* <li>{@link Article#ARTICLE_PERMALINK article permalink}</li>
* </ul>
* </ul>
* </p>
* </p>
*
*
* <p>
* <p>
* The batch version of method {@link #removeUnusedProperties(org.json.JSONObject)}.
* The batch version of method {@link #removeUnusedProperties(org.json.JSONObject)}.
* </p>
* </p>
*
*
* @param articles the specified articles
* @param articles the specified articles
* @see #removeUnusedProperties(org.json.JSONObject)
* @see #removeUnusedProperties(org.json.JSONObject)
*/
*/
public
void
removeUnusedProperties
(
final
List
<
JSONObject
>
articles
)
{
public
void
removeUnusedProperties
(
final
List
<
JSONObject
>
articles
)
{
for
(
final
JSONObject
article
:
articles
)
{
for
(
final
JSONObject
article
:
articles
)
{
removeUnusedProperties
(
article
);
removeUnusedProperties
(
article
);
}
}
}
}
/**
/**
* Removes unused properties of the specified article.
* Removes unused properties of the specified article.
*
*
* <p>
* <p>
* Remains the following properties:
* Remains the following properties:
* <ul>
* <ul>
* <li>{@link Article#ARTICLE_TITLE article title}</li>
* <li>{@link Article#ARTICLE_TITLE article title}</li>
* <li>{@link Article#ARTICLE_PERMALINK article permalink}</li>
* <li>{@link Article#ARTICLE_PERMALINK article permalink}</li>
* </ul>
* </ul>
* </p>
* </p>
*
*
* @param article the specified article
* @param article the specified article
* @see #removeUnusedProperties(java.util.List)
* @see #removeUnusedProperties(java.util.List)
*/
*/
public
void
removeUnusedProperties
(
final
JSONObject
article
)
{
public
void
removeUnusedProperties
(
final
JSONObject
article
)
{
article
.
remove
(
Keys
.
OBJECT_ID
);
article
.
remove
(
Keys
.
OBJECT_ID
);
article
.
remove
(
Article
.
ARTICLE_AUTHOR_EMAIL
);
article
.
remove
(
Article
.
ARTICLE_AUTHOR_EMAIL
);
article
.
remove
(
Article
.
ARTICLE_ABSTRACT
);
article
.
remove
(
Article
.
ARTICLE_ABSTRACT
);
article
.
remove
(
Article
.
ARTICLE_COMMENT_COUNT
);
article
.
remove
(
Article
.
ARTICLE_COMMENT_COUNT
);
article
.
remove
(
Article
.
ARTICLE_CONTENT
);
article
.
remove
(
Article
.
ARTICLE_CONTENT
);
article
.
remove
(
Article
.
ARTICLE_CREATE_DATE
);
article
.
remove
(
Article
.
ARTICLE_CREATE_DATE
);
article
.
remove
(
Article
.
ARTICLE_TAGS_REF
);
article
.
remove
(
Article
.
ARTICLE_TAGS_REF
);
article
.
remove
(
Article
.
ARTICLE_UPDATE_DATE
);
article
.
remove
(
Article
.
ARTICLE_UPDATE_DATE
);
article
.
remove
(
Article
.
ARTICLE_VIEW_COUNT
);
article
.
remove
(
Article
.
ARTICLE_VIEW_COUNT
);
article
.
remove
(
Article
.
ARTICLE_RANDOM_DOUBLE
);
article
.
remove
(
Article
.
ARTICLE_RANDOM_DOUBLE
);
article
.
remove
(
Article
.
ARTICLE_IS_PUBLISHED
);
article
.
remove
(
Article
.
ARTICLE_IS_PUBLISHED
);
article
.
remove
(
Article
.
ARTICLE_PUT_TOP
);
article
.
remove
(
Article
.
ARTICLE_PUT_TOP
);
article
.
remove
(
Article
.
ARTICLE_HAD_BEEN_PUBLISHED
);
article
.
remove
(
Article
.
ARTICLE_HAD_BEEN_PUBLISHED
);
}
}
/**
/**
* Gets the {@link ArticleQueryService} singleton.
* Gets the {@link ArticleQueryService} singleton.
*
*
* @return the singleton
* @return the singleton
*/
*/
public
static
ArticleQueryService
getInstance
()
{
public
static
ArticleQueryService
getInstance
()
{
return
SingletonHolder
.
SINGLETON
;
return
SingletonHolder
.
SINGLETON
;
}
}
/**
/**
* Private constructor.
* Private constructor.
*/
*/
private
ArticleQueryService
()
{
private
ArticleQueryService
()
{
}
}
/**
/**
* Singleton holder.
* Singleton holder.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.0, Oct 3, 2011
* @version 1.0.0.0, Oct 3, 2011
*/
*/
private
static
final
class
SingletonHolder
{
private
static
final
class
SingletonHolder
{
/**
/**
* Singleton.
* Singleton.
*/
*/
private
static
final
ArticleQueryService
SINGLETON
=
new
ArticleQueryService
();
private
static
final
ArticleQueryService
SINGLETON
=
new
ArticleQueryService
();
/**
/**
* Private default constructor.
* Private default constructor.
*/
*/
private
SingletonHolder
()
{
private
SingletonHolder
()
{
}
}
}
}
}
}
core/src/main/java/org/b3log/solo/util/Articles.java
View file @
65f8a5e9
/*
/*
* 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.FilterOperator
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.Query
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.RepositoryException
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.repository.SortDirection
;
import
org.b3log.latke.service.ServiceException
;
import
org.b3log.latke.service.ServiceException
;
import
org.b3log.latke.user.UserService
;
import
org.b3log.latke.user.UserService
;
import
org.b3log.latke.user.UserServiceFactory
;
import
org.b3log.latke.user.UserServiceFactory
;
import
org.b3log.latke.util.CollectionUtils
;
import
org.b3log.latke.util.CollectionUtils
;
import
org.b3log.latke.util.Strings
;
import
org.b3log.latke.util.Strings
;
import
org.b3log.solo.model.Common
;
import
org.b3log.solo.model.Common
;
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.UserRepository
;
import
org.b3log.solo.repository.UserRepository
;
import
org.b3log.solo.repository.impl.ArticleRepositoryImpl
;
import
org.b3log.solo.repository.impl.ArticleRepositoryImpl
;
import
org.b3log.solo.repository.impl.UserRepositoryImpl
;
import
org.b3log.solo.repository.impl.UserRepositoryImpl
;
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 utilities.
* Article utilities.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.2.8, May 6, 2012
* @version 1.0.2.8, May 6, 2012
* @since 0.3.1
* @since 0.3.1
*/
*/
public
final
class
Articles
{
public
final
class
Articles
{
/**
/**
* Logger.
* Logger.
*/
*/
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
Articles
.
class
.
getName
());
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
Articles
.
class
.
getName
());
/**
/**
* Article repository.
* Article repository.
*/
*/
private
ArticleRepository
articleRepository
=
ArticleRepositoryImpl
.
getInstance
();
private
ArticleRepository
articleRepository
=
ArticleRepositoryImpl
.
getInstance
();
/**
/**
* User repository.
* User repository.
*/
*/
private
UserRepository
userRepository
=
UserRepositoryImpl
.
getInstance
();
private
UserRepository
userRepository
=
UserRepositoryImpl
.
getInstance
();
/**
/**
* User service.
* User service.
*/
*/
private
UserService
userService
=
UserServiceFactory
.
getUserService
();
private
UserService
userService
=
UserServiceFactory
.
getUserService
();
/**
/**
* Builds article view password form parameters with the specified article.
* Builds article view password form parameters with the specified article.
*
*
* @param article the specified article
* @param article the specified article
* @return parameters string, for example,
* @return parameters string, for example,
* <pre>
* <pre>
* "?articleId=xxx&articleTitle=xxx&articlePermalink=xxx&articleAbstract=xxx"
* "?articleId=xxx&articleTitle=xxx&articlePermalink=xxx&articleAbstract=xxx"
* </pre>
* </pre>
* @throws UnsupportedEncodingException if can not encode the arguments
* @throws UnsupportedEncodingException if can not encode the arguments
*/
*/
public
String
buildArticleViewPwdFormParameters
(
final
JSONObject
article
)
throws
UnsupportedEncodingException
{
public
String
buildArticleViewPwdFormParameters
(
final
JSONObject
article
)
throws
UnsupportedEncodingException
{
final
StringBuilder
parametersBuilder
=
final
StringBuilder
parametersBuilder
=
new
StringBuilder
(
"?articleId="
).
append
(
article
.
optString
(
Keys
.
OBJECT_ID
)).
new
StringBuilder
(
"?articleId="
).
append
(
article
.
optString
(
Keys
.
OBJECT_ID
)).
append
(
"&articleTitle="
).
append
(
URLEncoder
.
encode
(
article
.
optString
(
Article
.
ARTICLE_TITLE
),
"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"
)).
append
(
"&articlePermalink="
).
append
(
URLEncoder
.
encode
(
article
.
optString
(
Article
.
ARTICLE_PERMALINK
),
"UTF-8"
)).
append
(
"&articleAbstract="
).
append
(
URLEncoder
.
encode
(
article
.
optString
(
Article
.
ARTICLE_ABSTRACT
,
" "
),
"UTF-8"
));
append
(
"&articleAbstract="
).
append
(
URLEncoder
.
encode
(
article
.
optString
(
Article
.
ARTICLE_ABSTRACT
,
" "
),
"UTF-8"
));
return
parametersBuilder
.
toString
();
return
parametersBuilder
.
toString
();
}
}
/**
/**
* Checks whether need password to view the specified article with the specified request.
* Checks whether need password to view the specified article with the specified request.
*
*
* <p>
* <p>
* Checks session, if not represents, checks article property {@link Article#ARTICLE_VIEW_PWD view password}.
* Checks session, if not represents, checks article property {@link Article#ARTICLE_VIEW_PWD view password}.
* </p>
* </p>
*
*
* <p>
* <p>
* The blogger itself dose not need view password never.
* The blogger itself dose not need view password never.
* </p>
* </p>
*
*
* @param request the specified request
* @param request the specified request
* @param article the specified article
* @param article the specified article
* @return {@code true} if need, returns {@code false} otherwise
* @return {@code true} if need, returns {@code false} otherwise
*/
*/
public
boolean
needViewPwd
(
final
HttpServletRequest
request
,
final
JSONObject
article
)
{
public
boolean
needViewPwd
(
final
HttpServletRequest
request
,
final
JSONObject
article
)
{
final
String
articleViewPwd
=
article
.
optString
(
Article
.
ARTICLE_VIEW_PWD
);
final
String
articleViewPwd
=
article
.
optString
(
Article
.
ARTICLE_VIEW_PWD
);
if
(
Strings
.
isEmptyOrNull
(
articleViewPwd
))
{
if
(
Strings
.
isEmptyOrNull
(
articleViewPwd
))
{
return
false
;
return
false
;
}
}
final
HttpSession
session
=
request
.
getSession
(
false
);
final
HttpSession
session
=
request
.
getSession
(
false
);
if
(
null
!=
session
)
{
if
(
null
!=
session
)
{
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
Map
<
String
,
String
>
viewPwds
=
(
Map
<
String
,
String
>)
session
.
getAttribute
(
Common
.
ARTICLES_VIEW_PWD
);
Map
<
String
,
String
>
viewPwds
=
(
Map
<
String
,
String
>)
session
.
getAttribute
(
Common
.
ARTICLES_VIEW_PWD
);
if
(
null
==
viewPwds
)
{
if
(
null
==
viewPwds
)
{
viewPwds
=
new
HashMap
<
String
,
String
>();
viewPwds
=
new
HashMap
<
String
,
String
>();
}
}
if
(
articleViewPwd
.
equals
(
viewPwds
.
get
(
article
.
optString
(
Keys
.
OBJECT_ID
))))
{
if
(
articleViewPwd
.
equals
(
viewPwds
.
get
(
article
.
optString
(
Keys
.
OBJECT_ID
))))
{
return
false
;
return
false
;
}
}
}
}
if
(
null
!=
userService
.
getCurrentUser
(
request
))
{
if
(
null
!=
userService
.
getCurrentUser
(
request
))
{
return
false
;
return
false
;
}
}
return
true
;
return
true
;
}
}
/**
/**
* Gets the specified article's author.
* Gets the specified article's author.
*
*
* <p>
* <p>
* The specified article has a property
* The specified article has a property
* {@value Article#ARTICLE_AUTHOR_EMAIL}, this method will use this property
* {@value Article#ARTICLE_AUTHOR_EMAIL}, this method will use this property
* to get a user from users.
* to get a user from users.
* </p>
* </p>
*
*
* <p>
* <p>
* If can't find the specified article's author (i.e. the author has been
* If can't find the specified article's author (i.e. the author has been
* removed by administrator), returns administrator.
* removed by administrator), returns administrator.
* </p>
* </p>
*
*
* @param article the specified article
* @param article the specified article
* @return user, {@code null} if not found
* @return user, {@code null} if not found
* @throws ServiceException service exception
* @throws ServiceException service exception
*/
*/
public
JSONObject
getAuthor
(
final
JSONObject
article
)
throws
ServiceException
{
public
JSONObject
getAuthor
(
final
JSONObject
article
)
throws
ServiceException
{
try
{
try
{
final
String
email
=
article
.
getString
(
Article
.
ARTICLE_AUTHOR_EMAIL
);
final
String
email
=
article
.
getString
(
Article
.
ARTICLE_AUTHOR_EMAIL
);
JSONObject
ret
=
userRepository
.
getByEmail
(
email
);
JSONObject
ret
=
userRepository
.
getByEmail
(
email
);
if
(
null
==
ret
)
{
if
(
null
==
ret
)
{
LOGGER
.
log
(
Level
.
WARNING
,
LOGGER
.
log
(
Level
.
WARNING
,
"Gets author of article failed, assumes the administrator is the author of this article[id={0}]"
,
"Gets author of article failed, assumes the administrator is the author of this article[id={0}]"
,
article
.
getString
(
Keys
.
OBJECT_ID
));
article
.
getString
(
Keys
.
OBJECT_ID
));
// This author may be deleted by admin, use admin as the author
// This author may be deleted by admin, use admin as the author
// of this article
// of this article
ret
=
userRepository
.
getAdmin
();
ret
=
userRepository
.
getAdmin
();
}
}
return
ret
;
return
ret
;
}
catch
(
final
RepositoryException
e
)
{
}
catch
(
final
RepositoryException
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
)
{
}
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
);
}
}
}
}
/**
/**
* Article comment count +1 for an article specified by the given article id.
* Article comment count +1 for an article specified by the given article id.
*
*
* @param articleId the given article id
* @param articleId the given article id
* @throws JSONException json exception
* @throws JSONException json exception
* @throws RepositoryException repository exception
* @throws RepositoryException repository exception
*/
*/
public
void
incArticleCommentCount
(
final
String
articleId
)
throws
JSONException
,
RepositoryException
{
public
void
incArticleCommentCount
(
final
String
articleId
)
throws
JSONException
,
RepositoryException
{
final
JSONObject
article
=
articleRepository
.
get
(
articleId
);
final
JSONObject
article
=
articleRepository
.
get
(
articleId
);
final
JSONObject
newArticle
=
new
JSONObject
(
article
,
JSONObject
.
getNames
(
article
));
final
JSONObject
newArticle
=
new
JSONObject
(
article
,
JSONObject
.
getNames
(
article
));
final
int
commentCnt
=
article
.
getInt
(
Article
.
ARTICLE_COMMENT_COUNT
);
final
int
commentCnt
=
article
.
getInt
(
Article
.
ARTICLE_COMMENT_COUNT
);
newArticle
.
put
(
Article
.
ARTICLE_COMMENT_COUNT
,
commentCnt
+
1
);
newArticle
.
put
(
Article
.
ARTICLE_COMMENT_COUNT
,
commentCnt
+
1
);
articleRepository
.
update
(
articleId
,
newArticle
);
articleRepository
.
update
(
articleId
,
newArticle
);
}
}
/**
/**
* Gets the sign of an article specified by the sign id.
* Gets the sign of an article specified by the sign id.
*
*
* @param signId the specified article id
* @param signId the specified article id
* @param preference the specified preference
* @param preference the specified preference
* @return article sign, returns the default sign (which oId is "1") if not found
* @return article sign, returns the default sign (which oId is "1") if not found
* @throws RepositoryException repository exception
* @throws RepositoryException repository exception
* @throws JSONException json exception
* @throws JSONException json exception
*/
*/
public
JSONObject
getSign
(
final
String
signId
,
final
JSONObject
preference
)
throws
JSONException
,
RepositoryException
{
public
JSONObject
getSign
(
final
String
signId
,
final
JSONObject
preference
)
throws
JSONException
,
RepositoryException
{
final
JSONArray
signs
=
new
JSONArray
(
preference
.
getString
(
Preference
.
SIGNS
));
final
JSONArray
signs
=
new
JSONArray
(
preference
.
getString
(
Preference
.
SIGNS
));
JSONObject
defaultSign
=
null
;
JSONObject
defaultSign
=
null
;
for
(
int
i
=
0
;
i
<
signs
.
length
();
i
++)
{
for
(
int
i
=
0
;
i
<
signs
.
length
();
i
++)
{
final
JSONObject
ret
=
signs
.
getJSONObject
(
i
);
final
JSONObject
ret
=
signs
.
getJSONObject
(
i
);
if
(
signId
.
equals
(
ret
.
optString
(
Keys
.
OBJECT_ID
)))
{
if
(
signId
.
equals
(
ret
.
optString
(
Keys
.
OBJECT_ID
)))
{
return
ret
;
return
ret
;
}
}
if
(
"1"
.
equals
(
ret
.
optString
(
Keys
.
OBJECT_ID
)))
{
if
(
"1"
.
equals
(
ret
.
optString
(
Keys
.
OBJECT_ID
)))
{
defaultSign
=
ret
;
defaultSign
=
ret
;
}
}
}
}
LOGGER
.
log
(
Level
.
WARNING
,
"Can not find the sign[id={0}], returns a default sign[id=1]"
,
signId
);
LOGGER
.
log
(
Level
.
WARNING
,
"Can not find the sign[id={0}], returns a default sign[id=1]"
,
signId
);
if
(
null
==
defaultSign
)
{
if
(
null
==
defaultSign
)
{
throw
new
IllegalStateException
(
"Can not find the default sign which id equals to 1"
);
throw
new
IllegalStateException
(
"Can not find the default sign which id equals to 1"
);
}
}
return
defaultSign
;
return
defaultSign
;
}
}
/**
/**
* Determines the specified article has updated.
* Determines the specified article has updated.
*
*
* @param article the specified article
* @param article the specified article
* @return {@code true} if it has updated, {@code false} otherwise
* @return {@code true} if it has updated, {@code false} otherwise
* @throws JSONException json exception
* @throws JSONException json exception
*/
*/
public
boolean
hasUpdated
(
final
JSONObject
article
)
throws
JSONException
{
public
boolean
hasUpdated
(
final
JSONObject
article
)
throws
JSONException
{
final
Date
updateDate
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_UPDATE_DATE
);
final
Date
updateDate
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_UPDATE_DATE
);
final
Date
createDate
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_CREATE_DATE
);
final
Date
createDate
=
(
Date
)
article
.
get
(
Article
.
ARTICLE_CREATE_DATE
);
return
!
createDate
.
equals
(
updateDate
);
return
!
createDate
.
equals
(
updateDate
);
}
}
/**
/**
* Determines the specified article had been published.
* Determines the specified article had been published.
*
*
* @param article the specified article
* @param article the specified article
* @return {@code true} if it had been published, {@code false} otherwise
* @return {@code true} if it had been published, {@code false} otherwise
* @throws JSONException json exception
* @throws JSONException json exception
*/
*/
public
boolean
hadBeenPublished
(
final
JSONObject
article
)
throws
JSONException
{
public
boolean
hadBeenPublished
(
final
JSONObject
article
)
throws
JSONException
{
return
article
.
getBoolean
(
Article
.
ARTICLE_HAD_BEEN_PUBLISHED
);
return
article
.
getBoolean
(
Article
.
ARTICLE_HAD_BEEN_PUBLISHED
);
}
}
/**
/**
* Gets all unpublished articles.
* Gets all unpublished articles.
*
*
* @return articles all unpublished articles
* @return articles all unpublished articles
* @throws RepositoryException repository exception
* @throws RepositoryException repository exception
* @throws JSONException json exception
* @throws JSONException json exception
*/
*/
public
List
<
JSONObject
>
getUnpublishedArticles
()
throws
RepositoryException
,
JSONException
{
public
List
<
JSONObject
>
getUnpublishedArticles
()
throws
RepositoryException
,
JSONException
{
final
Map
<
String
,
SortDirection
>
sorts
=
new
HashMap
<
String
,
SortDirection
>();
final
Map
<
String
,
SortDirection
>
sorts
=
new
HashMap
<
String
,
SortDirection
>();
sorts
.
put
(
Article
.
ARTICLE_CREATE_DATE
,
SortDirection
.
DESCENDING
);
sorts
.
put
(
Article
.
ARTICLE_CREATE_DATE
,
SortDirection
.
DESCENDING
);
sorts
.
put
(
Article
.
ARTICLE_PUT_TOP
,
SortDirection
.
DESCENDING
);
sorts
.
put
(
Article
.
ARTICLE_PUT_TOP
,
SortDirection
.
DESCENDING
);
final
Query
query
=
new
Query
().
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
);
final
Query
query
=
new
Query
().
addFilter
(
Article
.
ARTICLE_IS_PUBLISHED
,
FilterOperator
.
EQUAL
,
true
);
final
JSONObject
result
=
articleRepository
.
get
(
query
);
final
JSONObject
result
=
articleRepository
.
get
(
query
);
final
JSONArray
articles
=
result
.
getJSONArray
(
Keys
.
RESULTS
);
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
()
{
public
static
Articles
getInstance
()
{
return
SingletonHolder
.
SINGLETON
;
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>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.0, Jan 12, 2011
* @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
()
{
}
}
}
}
}
}
core/src/test/java/org/b3log/solo/repository/impl/UserRepositoryImplTestCase.java
View file @
65f8a5e9
/*
/*
* 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.Query
;
import
org.b3log.latke.repository.Transaction
;
import
org.b3log.latke.repository.Transaction
;
import
org.b3log.solo.AbstractTestCase
;
import
org.b3log.solo.AbstractTestCase
;
import
org.b3log.solo.model.UserExt
;
import
org.b3log.solo.model.UserExt
;
import
org.b3log.solo.repository.UserRepository
;
import
org.b3log.solo.repository.UserRepository
;
import
org.json.JSONArray
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.json.JSONObject
;
import
org.testng.Assert
;
import
org.testng.Assert
;
import
org.testng.annotations.Test
;
import
org.testng.annotations.Test
;
/**
/**
* {@link UserRepositoryImpl} test case.
* {@link UserRepositoryImpl} test case.
*
*
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.1, Feb 21, 2012
* @version 1.0.0.1, Feb 21, 2012
*/
*/
@Test
(
suiteName
=
"repository"
)
@Test
(
suiteName
=
"repository"
)
public
final
class
UserRepositoryImplTestCase
extends
AbstractTestCase
{
public
final
class
UserRepositoryImplTestCase
extends
AbstractTestCase
{
/**
/**
* Tests.
* Tests.
*
*
* @throws Exception exception
* @throws Exception exception
*/
*/
@Test
@Test
public
void
test
()
throws
Exception
{
public
void
test
()
throws
Exception
{
final
UserRepository
userRepository
=
getUserRepository
();
final
UserRepository
userRepository
=
getUserRepository
();
final
JSONObject
another
=
new
JSONObject
();
final
JSONObject
another
=
new
JSONObject
();
another
.
put
(
User
.
USER_NAME
,
"test1"
);
another
.
put
(
User
.
USER_NAME
,
"test1"
);
another
.
put
(
User
.
USER_EMAIL
,
"test1@gmail.com"
);
another
.
put
(
User
.
USER_EMAIL
,
"test1@gmail.com"
);
another
.
put
(
User
.
USER_PASSWORD
,
"pass1"
);
another
.
put
(
User
.
USER_PASSWORD
,
"pass1"
);
another
.
put
(
User
.
USER_ROLE
,
Role
.
DEFAULT_ROLE
);
another
.
put
(
User
.
USER_ROLE
,
Role
.
DEFAULT_ROLE
);
another
.
put
(
UserExt
.
USER_ARTICLE_COUNT
,
0
);
another
.
put
(
UserExt
.
USER_ARTICLE_COUNT
,
0
);
another
.
put
(
UserExt
.
USER_PUBLISHED_ARTICLE_COUNT
,
0
);
another
.
put
(
UserExt
.
USER_PUBLISHED_ARTICLE_COUNT
,
0
);
Transaction
transaction
=
userRepository
.
beginTransaction
();
Transaction
transaction
=
userRepository
.
beginTransaction
();
userRepository
.
add
(
another
);
userRepository
.
add
(
another
);
transaction
.
commit
();
transaction
.
commit
();
Assert
.
assertNull
(
userRepository
.
getAdmin
());
Assert
.
assertNull
(
userRepository
.
getAdmin
());
JSONObject
admin
=
new
JSONObject
();
JSONObject
admin
=
new
JSONObject
();
admin
.
put
(
User
.
USER_NAME
,
"test"
);
admin
.
put
(
User
.
USER_NAME
,
"test"
);
admin
.
put
(
User
.
USER_EMAIL
,
"test@gmail.com"
);
admin
.
put
(
User
.
USER_EMAIL
,
"test@gmail.com"
);
admin
.
put
(
User
.
USER_PASSWORD
,
"pass"
);
admin
.
put
(
User
.
USER_PASSWORD
,
"pass"
);
admin
.
put
(
User
.
USER_ROLE
,
Role
.
ADMIN_ROLE
);
admin
.
put
(
User
.
USER_ROLE
,
Role
.
ADMIN_ROLE
);
admin
.
put
(
UserExt
.
USER_ARTICLE_COUNT
,
0
);
admin
.
put
(
UserExt
.
USER_ARTICLE_COUNT
,
0
);
admin
.
put
(
UserExt
.
USER_PUBLISHED_ARTICLE_COUNT
,
0
);
admin
.
put
(
UserExt
.
USER_PUBLISHED_ARTICLE_COUNT
,
0
);
transaction
=
userRepository
.
beginTransaction
();
transaction
=
userRepository
.
beginTransaction
();
userRepository
.
add
(
admin
);
userRepository
.
add
(
admin
);
transaction
.
commit
();
transaction
.
commit
();
Assert
.
assertTrue
(
userRepository
.
isAdminEmail
(
"test@gmail.com"
));
Assert
.
assertTrue
(
userRepository
.
isAdminEmail
(
"test@gmail.com"
));
Assert
.
assertFalse
(
userRepository
.
isAdminEmail
(
"notFound@gmail.com"
));
Assert
.
assertFalse
(
userRepository
.
isAdminEmail
(
"notFound@gmail.com"
));
admin
=
userRepository
.
getAdmin
();
admin
=
userRepository
.
getAdmin
();
Assert
.
assertNotNull
(
admin
);
Assert
.
assertNotNull
(
admin
);
Assert
.
assertEquals
(
"test"
,
admin
.
optString
(
User
.
USER_NAME
));
Assert
.
assertEquals
(
"test"
,
admin
.
optString
(
User
.
USER_NAME
));
final
JSONObject
result
=
final
JSONObject
result
=
userRepository
.
get
(
new
Query
().
addFilter
(
User
.
USER_NAME
,
userRepository
.
get
(
new
Query
().
addFilter
(
User
.
USER_NAME
,
FilterOperator
.
EQUAL
,
FilterOperator
.
EQUAL
,
"test1"
));
"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"
);
}
}
}
}
war/src/main/webapp/skins/ease/css/ease.css
View file @
65f8a5e9
/*
/*
* 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.
*/
*/
/*
/*
* skin ease style
* skin ease style
*
*
* @author <a href="mailto:LLY219@gmail.com">Liyuan Li</a>
* @author <a href="mailto:LLY219@gmail.com">Liyuan Li</a>
* @version 1.0.1.3, Jun 27, 2012
* @version 1.0.1.3, Jun 27, 2012
*/
*/
/* start base */
/* start base */
html
,
body
,
div
,
ul
,
li
{
html
,
body
,
div
,
ul
,
li
{
margin
:
0
;
margin
:
0
;
padding
:
0
;
padding
:
0
;
}
}
body
{
body
{
font-family
:
Verdana
,
arial
,
\
5
fae
\
8
f6f
\
96
c5
\
9
ed1
;
font-family
:
Verdana
,
arial
,
\
5
fae
\
8
f6f
\
96
c5
\
9
ed1
;
font-size
:
12px
;
font-size
:
12px
;
}
}
a
{
a
{
outline
:
none
;
outline
:
none
;
color
:
#009EB8
;
color
:
#009EB8
;
text-decoration
:
none
;
text-decoration
:
none
;
}
}
a
:visited
{
a
:visited
{
color
:
#00b4d2
;
color
:
#00b4d2
;
}
}
a
:hover
{
a
:hover
{
text-decoration
:
underline
;
text-decoration
:
underline
;
}
}
a
:active
{
a
:active
{
color
:
#00889f
;
color
:
#00889f
;
}
}
img
{
img
{
vertical-align
:
middle
;
vertical-align
:
middle
;
border
:
0
;
border
:
0
;
}
}
textarea
,
input
{
textarea
,
input
{
outline
:
none
;
outline
:
none
;
}
}
sup
{
sup
{
font-size
:
10px
;
font-size
:
10px
;
font-weight
:
normal
;
font-weight
:
normal
;
-webkit-text-size-adjust
:
none
;
-webkit-text-size-adjust
:
none
;
}
}
.left
{
.left
{
float
:
left
;
float
:
left
;
}
}
.right
{
.right
{
float
:
right
;
float
:
right
;
}
}
.clear
{
.clear
{
background-color
:
transparent
;
background-color
:
transparent
;
border
:
0
;
border
:
0
;
clear
:
both
;
clear
:
both
;
display
:
block
;
display
:
block
;
font-size
:
0
;
font-size
:
0
;
height
:
0
;
height
:
0
;
line-height
:
0
;
line-height
:
0
;
overflow
:
hidden
;
overflow
:
hidden
;
}
}
.none
{
.none
{
display
:
none
;
display
:
none
;
}
}
.ft-gray
{
.ft-gray
{
color
:
#808080
;
color
:
#808080
;
}
}
.ft-gray
:visited
{
.ft-gray
:visited
{
color
:
#9a9a9a
color
:
#9a9a9a
}
}
.ft-gray
:hover
{
.ft-gray
:hover
{
color
:
#676767
;
color
:
#676767
;
text-decoration
:
none
;
text-decoration
:
none
;
}
}
.logo
{
.logo
{
padding
:
0
5px
;
padding
:
0
5px
;
text-shadow
:
0
0
1px
#D5D5D5
;
text-shadow
:
0
0
1px
#D5D5D5
;
}
}
.em00
,
.em01
,
.em02
,
.em03
,
.em04
,
.em05
,
.em06
,
.em07
,
.em08
,
.em09
,
.em00
,
.em01
,
.em02
,
.em03
,
.em04
,
.em05
,
.em06
,
.em07
,
.em08
,
.em09
,
.em10
,
.em11
,
.em12
,
.em13
,
.em14
{
.em10
,
.em11
,
.em12
,
.em13
,
.em14
{
cursor
:
pointer
;
cursor
:
pointer
;
background-image
:
url("../../ease/images/emotions/emotions-ease.png")
;
background-image
:
url("../../ease/images/emotions/emotions-ease.png")
;
float
:
left
;
float
:
left
;
height
:
24px
;
height
:
24px
;
margin-right
:
5px
;
margin-right
:
5px
;
width
:
24px
;
width
:
24px
;
transition
:
all
.2s
ease-out
;
transition
:
all
.2s
ease-out
;
-webkit-transition
:
all
.2s
ease-out
;
-webkit-transition
:
all
.2s
ease-out
;
-moz-transition
:
all
.2s
ease-out
;
-moz-transition
:
all
.2s
ease-out
;
}
}
#emotions
span
:hover
{
#emotions
span
:hover
{
transform
:
scale
(
1.2
)
rotate
(
360deg
);
transform
:
scale
(
1.2
)
rotate
(
360deg
);
-webkit-transform
:
scale
(
1.2
)
rotate
(
360deg
);
-webkit-transform
:
scale
(
1.2
)
rotate
(
360deg
);
-moz-transform
:
scale
(
1.2
)
rotate
(
360deg
);
-moz-transform
:
scale
(
1.2
)
rotate
(
360deg
);
}
}
.em01
{
.em01
{
background-position
:
-24px
0
;
background-position
:
-24px
0
;
}
}
.em02
{
.em02
{
background-position
:
-48px
0
;
background-position
:
-48px
0
;
}
}
.em03
{
.em03
{
background-position
:
-72px
0
;
background-position
:
-72px
0
;
}
}
.em04
{
.em04
{
background-position
:
-96px
1px
;
background-position
:
-96px
1px
;
}
}
.em05
{
.em05
{
background-position
:
0
-24px
;
background-position
:
0
-24px
;
}
}
.em06
{
.em06
{
background-position
:
-24px
-24px
;
background-position
:
-24px
-24px
;
}
}
.em07
{
.em07
{
background-position
:
-48px
-24px
;
background-position
:
-48px
-24px
;
}
}
.em08
{
.em08
{
background-position
:
-72px
-24px
;
background-position
:
-72px
-24px
;
}
}
.em09
{
.em09
{
background-position
:
-96px
-24px
;
background-position
:
-96px
-24px
;
}
}
.em10
{
.em10
{
background-position
:
0
-48px
;
background-position
:
0
-48px
;
}
}
.em11
{
.em11
{
background-position
:
-24px
-48px
;
background-position
:
-24px
-48px
;
}
}
.em12
{
.em12
{
background-position
:
-48px
-48px
;
background-position
:
-48px
-48px
;
}
}
.em13
{
.em13
{
background-position
:
-72px
-48px
;
background-position
:
-72px
-48px
;
}
}
.em14
{
.em14
{
background-position
:
-96px
-48px
;
background-position
:
-96px
-48px
;
}
}
/* end base */
/* end base */
/* start ico */
/* start ico */
#search
,
#search
,
.translate-ico
{
.translate-ico
{
background-image
:
url("/skins/ease/images/icons.png")
;
background-image
:
url("/skins/ease/images/icons.png")
;
}
}
.translate-ico
{
.translate-ico
{
background-position
:
1px
-125px
;
background-position
:
1px
-125px
;
background-repeat
:
no-repeat
;
background-repeat
:
no-repeat
;
border
:
1px
solid
#D5D5D5
;
border
:
1px
solid
#D5D5D5
;
border-radius
:
3px
;
border-radius
:
3px
;
cursor
:
pointer
;
cursor
:
pointer
;
float
:
right
;
float
:
right
;
height
:
16px
;
height
:
16px
;
margin
:
-3px
0
0
15px
;
;
margin
:
-3px
0
0
15px
;
;
padding
:
1px
;
padding
:
1px
;
width
:
16px
;
width
:
16px
;
}
}
.translate-ico
:hover
{
.translate-ico
:hover
{
border-color
:
#9a9a9a
;
border-color
:
#9a9a9a
;
box-shadow
:
0
0
1px
#808080
;
box-shadow
:
0
0
1px
#808080
;
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
}
}
/* end ico */
/* end ico */
/* start frame */
/* start frame */
.wrapper
{
.wrapper
{
margin
:
0
50px
;
margin
:
0
50px
;
}
}
.body
{
.body
{
margin
:
0
auto
50px
;
margin
:
0
auto
50px
;
width
:
990px
;
width
:
990px
;
}
}
/* end frame */
/* end frame */
/* start header */
/* start header */
.header
{
.header
{
width
:
100%
;
width
:
100%
;
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
z-index
:
1
;
z-index
:
1
;
}
}
.header
.title
{
.header
.title
{
border-bottom
:
1px
solid
#808080
;
border-bottom
:
1px
solid
#808080
;
font-size
:
26px
;
font-size
:
26px
;
font-weight
:
normal
;
font-weight
:
normal
;
}
}
.header
.sub-title
{
.header
.sub-title
{
font-size
:
11px
;
font-size
:
11px
;
}
}
#search
{
#search
{
background-position
:
7px
-99px
;
background-position
:
7px
-99px
;
background-repeat
:
no-repeat
;
background-repeat
:
no-repeat
;
background-color
:
#FFF
;
background-color
:
#FFF
;
border
:
1px
solid
#D5D5D5
;
border
:
1px
solid
#D5D5D5
;
border-radius
:
2px
2px
2px
2px
;
border-radius
:
2px
2px
2px
2px
;
box-shadow
:
0
1px
1px
rgba
(
0
,
0
,
0
,
0.1
)
inset
;
box-shadow
:
0
1px
1px
rgba
(
0
,
0
,
0
,
0.1
)
inset
;
color
:
#808080
;
color
:
#808080
;
float
:
right
;
float
:
right
;
font-size
:
14px
;
font-size
:
14px
;
height
:
19px
;
height
:
19px
;
line-height
:
145%
;
line-height
:
145%
;
padding
:
4px
10px
4px
28px
;
padding
:
4px
10px
4px
28px
;
width
:
24px
;
width
:
24px
;
-moz-transition
:
width
0.4s
ease
,
background
0.4s
ease
;
-moz-transition
:
width
0.4s
ease
,
background
0.4s
ease
;
-webkit-transition
:
width
0.4s
ease
,
background
0.4s
ease
;
-webkit-transition
:
width
0.4s
ease
,
background
0.4s
ease
;
transition
:
width
0.4s
ease
,
background
0.4s
ease
;
transition
:
width
0.4s
ease
,
background
0.4s
ease
;
}
}
#search
:focus
{
#search
:focus
{
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
width
:
196px
;
width
:
196px
;
}
}
.banner
{
.banner
{
margin-bottom
:
20px
;
margin-bottom
:
20px
;
}
}
.banner
.notice
{
.banner
.notice
{
float
:
left
;
float
:
left
;
margin
:
20px
0
0
50px
;
margin
:
20px
0
0
50px
;
}
}
.nav
{
.nav
{
background-color
:
#2C2C2C
;
background-color
:
#2C2C2C
;
box-shadow
:
0
2px
2px
#D5D5D5
,
0
3px
3px
-3px
#D5D5D5
inset
;
box-shadow
:
0
2px
2px
#D5D5D5
,
0
3px
3px
-3px
#D5D5D5
inset
;
height
:
29px
;
height
:
29px
;
top
:
0
;
top
:
0
;
width
:
100%
;
width
:
100%
;
}
}
.nav
ul
{
.nav
ul
{
list-style
:
none
;
list-style
:
none
;
float
:
left
;
float
:
left
;
}
}
.nav
li
{
.nav
li
{
float
:
left
;
float
:
left
;
}
}
.nav
a
{
.nav
a
{
color
:
#C9C9C9
;
color
:
#C9C9C9
;
display
:
block
;
display
:
block
;
float
:
left
;
float
:
left
;
font-size
:
14px
;
font-size
:
14px
;
font-weight
:
700
;
font-weight
:
700
;
line-height
:
29px
;
line-height
:
29px
;
margin-right
:
20px
;
margin-right
:
20px
;
padding
:
0
10px
;
padding
:
0
10px
;
text-decoration
:
none
;
text-decoration
:
none
;
transition
:
color
.4s
ease
,
background-color
.8s
ease
;
transition
:
color
.4s
ease
,
background-color
.8s
ease
;
-webkit-transition
:
color
.4s
ease
,
background-color
.8s
ease
;
-webkit-transition
:
color
.4s
ease
,
background-color
.8s
ease
;
-moz-transition
:
color
.4s
ease
,
background-color
.8s
ease
;
-moz-transition
:
color
.4s
ease
,
background-color
.8s
ease
;
}
}
.nav
a
:hover
{
.nav
a
:hover
{
color
:
#FFF
;
color
:
#FFF
;
background-color
:
#535353
;
background-color
:
#535353
;
}
}
.nav
a
.current
{
.nav
a
.current
{
background-color
:
#FFF
;
background-color
:
#FFF
;
box-shadow
:
0
-1px
1px
rgba
(
0
,
0
,
0
,
0.1
)
inset
,
0
1px
1px
rgba
(
0
,
0
,
0
,
0.1
)
inset
;
box-shadow
:
0
-1px
1px
rgba
(
0
,
0
,
0
,
0.1
)
inset
,
0
1px
1px
rgba
(
0
,
0
,
0
,
0.1
)
inset
;
color
:
#808080
;
color
:
#808080
;
}
}
.nav
img
{
.nav
img
{
margin-left
:
3px
;
margin-left
:
3px
;
}
}
/* end header */
/* end header */
/* start footer */
/* start footer */
.footer
{
.footer
{
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
border-top
:
2px
solid
#D5D5D5
;
border-top
:
2px
solid
#D5D5D5
;
font-size
:
11px
;
font-size
:
11px
;
padding
:
12px
0
;
padding
:
12px
0
;
-webkit-text-size-adjust
:
none
;
-webkit-text-size-adjust
:
none
;
}
}
#goTop
{
#goTop
{
background
:
url("/skins/ease/images/icons.png")
no-repeat
scroll
5px
-51px
#D5D5D5
;
background
:
url("/skins/ease/images/icons.png")
no-repeat
scroll
5px
-51px
#D5D5D5
;
border-radius
:
2px
2px
0
0
;
border-radius
:
2px
2px
0
0
;
cursor
:
pointer
;
cursor
:
pointer
;
font-size
:
11px
;
font-size
:
11px
;
height
:
21px
;
height
:
21px
;
line-height
:
21px
;
line-height
:
21px
;
padding
:
0
10px
0
23px
;
padding
:
0
10px
0
23px
;
position
:
absolute
;
position
:
absolute
;
right
:
50px
;
right
:
50px
;
display
:
none
;
display
:
none
;
}
}
#goTop
:hover
{
#goTop
:hover
{
background-color
:
#D5D5D5
;
background-color
:
#D5D5D5
;
}
}
/* end footer*/
/* end footer*/
/* start article list */
/* start article list */
.body
>
ul
{
.body
>
ul
{
list-style
:
none
;
list-style
:
none
;
}
}
.article
{
.article
{
border-bottom
:
1px
solid
#f6f6f6
;
border-bottom
:
1px
solid
#f6f6f6
;
padding
:
20px
70px
20px
;
padding
:
20px
70px
20px
;
}
}
.article
:hover
{
.article
:hover
{
border-bottom-color
:
#D5D5D5
;
border-bottom-color
:
#D5D5D5
;
box-shadow
:
0
0
1px
#f6f6f6
inset
;
box-shadow
:
0
0
1px
#f6f6f6
inset
;
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
}
}
.article-body
{
.article-body
{
line-height
:
145%
;
line-height
:
145%
;
overflow
:
hidden
;
overflow
:
hidden
;
word-wrap
:
break-word
;
word-wrap
:
break-word
;
}
}
.article-body
ol
,
.article-body
ul
{
.article-body
ol
,
.article-body
ul
{
margin-left
:
40px
;
margin-left
:
40px
;
}
}
.article-body
a
{
.article-body
a
{
color
:
#808080
;
color
:
#808080
;
text-decoration
:
underline
;
text-decoration
:
underline
;
}
}
.article-body
a
:vidited
{
.article-body
a
:vidited
{
color
:
#9a9a9a
color
:
#9a9a9a
}
}
.article-body
a
:hover
{
.article-body
a
:hover
{
color
:
#676767
;
color
:
#676767
;
}
}
.article-body
>
div
{
.article-body
>
div
{
min-height
:
32px
;
min-height
:
32px
;
}
}
.article-title
h2
{
.article-title
h2
{
display
:
inline
;
display
:
inline
;
}
}
.article-title
span
{
.article-title
span
{
cursor
:
pointer
;
cursor
:
pointer
;
}
}
.article-next
{
.article-next
{
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
box-shadow
:
0
0
3px
#D5D5D5
inset
;
box-shadow
:
0
0
3px
#D5D5D5
inset
;
cursor
:
pointer
;
cursor
:
pointer
;
font-size
:
14px
;
font-size
:
14px
;
line-height
:
36px
;
line-height
:
36px
;
text-align
:
center
;
text-align
:
center
;
}
}
.article-next
:hover
{
.article-next
:hover
{
box-shadow
:
0
0
3px
#D5D5D5
,
0
0
3px
#D5D5D5
inset
;
box-shadow
:
0
0
3px
#D5D5D5
,
0
0
3px
#D5D5D5
inset
;
}
}
/* end article list */
/* end article list */
/* start article */
/* start article */
.article-relative
{
.article-relative
{
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
box-shadow
:
0
0
2px
#D5D5D5
;
float
:
left
;
float
:
left
;
margin
:
20px
0
;
margin
:
20px
0
;
padding
:
0
20px
10px
;
padding
:
0
20px
10px
;
width
:
365px
;
width
:
365px
;
}
}
.article-relative
:hover
{
.article-relative
:hover
{
background-color
:
#fff
;
background-color
:
#fff
;
box-shadow
:
0
0
4px
#D5D5D5
;
box-shadow
:
0
0
4px
#D5D5D5
;
}
}
.article-relative
ul
{
.article-relative
ul
{
list-style
:
none
;
list-style
:
none
;
}
}
#relevantArticles
{
#relevantArticles
{
margin-right
:
40px
;
margin-right
:
40px
;
}
}
#externalRelevantArticles
{
#externalRelevantArticles
{
width
:
297px
;
width
:
297px
;
margin-top
:
0
;
margin-top
:
0
;
}
}
/* end article*/
/* end article*/
/* start comment */
/* start comment */
#comments
{
#comments
{
padding
:
20px
70px
20px
;
padding
:
20px
70px
20px
;
position
:
relative
;
position
:
relative
;
}
}
.comment-header
{
.comment-header
{
float
:
left
;
float
:
left
;
background-color
:
#FFF
;
background-color
:
#FFF
;
border
:
1px
solid
#DEDEDE
;
border
:
1px
solid
#DEDEDE
;
padding
:
2px
;
padding
:
2px
;
height
:
60px
;
height
:
60px
;
width
:
60px
;
width
:
60px
;
}
}
.comment-panel
{
.comment-panel
{
float
:
left
;
float
:
left
;
line-height
:
16px
;
line-height
:
16px
;
margin
:
0
10px
20px
;
margin
:
0
10px
20px
;
min-height
:
64px
;
min-height
:
64px
;
overflow
:
hidden
;
overflow
:
hidden
;
width
:
760px
;
width
:
760px
;
}
}
.comment-body-ref
{
.comment-body-ref
{
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
box-shadow
:
0
0
2px
#D5D5D5
;
display
:
block
;
display
:
block
;
left
:
140px
;
left
:
140px
;
padding
:
10px
;
padding
:
10px
;
opacity
:
0.9
;
opacity
:
0.9
;
filter
:
alpha
(
opacity
=
90
);
filter
:
alpha
(
opacity
=
90
);
position
:
absolute
;
position
:
absolute
;
}
}
.comment-body-ref
>
.comment-header
{
.comment-body-ref
>
.comment-header
{
border
:
0
none
;
border
:
0
none
;
float
:
right
;
float
:
right
;
height
:
48px
;
height
:
48px
;
width
:
48px
;
width
:
48px
;
padding
:
0
;
padding
:
0
;
}
}
.comment-body-ref
>
.comment-panel
{
.comment-body-ref
>
.comment-panel
{
margin
:
0
20px
0
0
;
margin
:
0
20px
0
0
;
min-height
:
48px
;
min-height
:
48px
;
width
:
756px
;
width
:
756px
;
}
}
.form
{
.form
{
padding
:
0
70px
20px
;
padding
:
0
70px
20px
;
float
:
left
;
float
:
left
;
}
}
.form
th
{
.form
th
{
text-align
:
right
;
text-align
:
right
;
white-space
:
nowrap
;
white-space
:
nowrap
;
}
}
.form
input
[
type
=
"text"
],
.form
input
[
type
=
"text"
],
.form
input
[
type
=
"password"
],
.form
input
[
type
=
"password"
],
.form
textarea
{
.form
textarea
{
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
border-width
:
0
;
border-width
:
0
;
box-shadow
:
0
0
2px
#BCBCBC
;
box-shadow
:
0
0
2px
#BCBCBC
;
font-family
:
Verdana
,
arial
,
\
5
fae
\
8
f6f
\
96
c5
\
9
ed1
;
font-family
:
Verdana
,
arial
,
\
5
fae
\
8
f6f
\
96
c5
\
9
ed1
;
font-size
:
12px
;
font-size
:
12px
;
margin
:
0
5px
10px
0
;
margin
:
0
5px
10px
0
;
outline
:
medium
none
;
outline
:
medium
none
;
padding
:
0
3px
;
padding
:
0
3px
;
height
:
28px
;
height
:
28px
;
line-height
:
28px
;
line-height
:
28px
;
width
:
260px
;
width
:
260px
;
}
}
.form
input
:focus
,
.form
input
:focus
,
.form
textarea
:focus
{
.form
textarea
:focus
{
box-shadow
:
0
0
4px
#D5D5D5
;
box-shadow
:
0
0
4px
#D5D5D5
;
}
}
.form
textarea
{
.form
textarea
{
height
:
120px
;
height
:
120px
;
overflow
:
auto
;
overflow
:
auto
;
width
:
426px
;
width
:
426px
;
line-height
:
16px
;
line-height
:
16px
;
}
}
.form
button
{
.form
button
{
background-color
:
#F6F6F6
;
background-color
:
#F6F6F6
;
border
:
0
none
;
border
:
0
none
;
box-shadow
:
0
0
2px
#D5D5D5
;
box-shadow
:
0
0
2px
#D5D5D5
;
height
:
28px
;
height
:
28px
;
line-height
:
28px
;
line-height
:
28px
;
padding
:
0
12px
;
padding
:
0
12px
;
color
:
#A7A7A7
;
color
:
#A7A7A7
;
}
}
.form
button
:hover
{
.form
button
:hover
{
box-shadow
:
0
0
4px
#D5D5D5
;
box-shadow
:
0
0
4px
#D5D5D5
;
text-shadow
:
0
0
2px
;
text-shadow
:
0
0
2px
;
}
}
.form
img
{
.form
img
{
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
box-shadow
:
0
0
2px
#D5D5D5
;
cursor
:
pointer
;
cursor
:
pointer
;
height
:
24px
;
height
:
24px
;
padding
:
1px
;
padding
:
1px
;
}
}
/* end comment */
/* end comment */
/* start tags */
/* start tags */
#tags
li
{
#tags
li
{
float
:
left
;
float
:
left
;
height
:
38px
;
height
:
38px
;
}
}
#tags
a
{
#tags
a
{
margin
:
3px
6px
;
margin
:
3px
6px
;
padding
:
3px
12px
;
padding
:
3px
12px
;
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
box-shadow
:
0
0
2px
#D5D5D5
;
float
:
left
;
float
:
left
;
}
}
#tags
a
:hover
{
#tags
a
:hover
{
text-shadow
:
0
0
2px
;
text-shadow
:
0
0
2px
;
text-decoration
:
none
;
text-decoration
:
none
;
box-shadow
:
0
0
4px
#D5D5D5
;
box-shadow
:
0
0
4px
#D5D5D5
;
}
}
.tags1
,
.tags1
:visited
{
.tags1
,
.tags1
:visited
{
font-size
:
12px
;
font-size
:
12px
;
color
:
#a7a7a7
;
color
:
#a7a7a7
;
}
}
.tags2
,
.tags2
:visited
{
.tags2
,
.tags2
:visited
{
font-size
:
14px
;
font-size
:
14px
;
color
:
#808080
;
color
:
#808080
;
}
}
.tags3
,
.tags3
:visited
{
.tags3
,
.tags3
:visited
{
font-size
:
16px
;
font-size
:
16px
;
color
:
#595959
;
color
:
#595959
;
}
}
.tags4
,
.tags4
:visited
{
.tags4
,
.tags4
:visited
{
font-size
:
18px
;
font-size
:
18px
;
color
:
#323232
;
color
:
#323232
;
}
}
.tags5
,
.tags5
:visited
{
.tags5
,
.tags5
:visited
{
font-size
:
20px
;
font-size
:
20px
;
color
:
#0a0a0a
;
color
:
#0a0a0a
;
}
}
/* end tags */
/* end tags */
/* start archives */
/* start archives */
.archives
{
.archives
{
position
:
relative
;
position
:
relative
;
}
}
.archives
>
div
{
.archives
>
div
{
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
box-shadow
:
0
0
2px
#D5D5D5
;
padding-bottom
:
20px
;
padding-bottom
:
20px
;
line-height
:
20px
;
line-height
:
20px
;
margin
:
20px
;
margin
:
20px
;
width
:
276px
;
width
:
276px
;
position
:
absolute
;
position
:
absolute
;
top
:
0
;
top
:
0
;
}
}
.archives
h3
{
.archives
h3
{
text-align
:
center
;
text-align
:
center
;
}
}
.archives
>
div
:hover
{
.archives
>
div
:hover
{
box-shadow
:
0
0
4px
#D5D5D5
;
box-shadow
:
0
0
4px
#D5D5D5
;
}
}
.archives
a
{
.archives
a
{
display
:
block
;
display
:
block
;
margin-left
:
80px
;
margin-left
:
80px
;
}
}
/* end archives */
/* end archives */
/* start dynamic */
/* start dynamic */
.dynamic
ul
{
.dynamic
ul
{
list-style
:
none
;
list-style
:
none
;
}
}
.dynamic
h3
{
.dynamic
h3
{
text-align
:
center
;
text-align
:
center
;
}
}
.dynamic
.module
{
.dynamic
.module
{
background-color
:
#FCFCFC
;
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
box-shadow
:
0
0
2px
#D5D5D5
;
float
:
left
;
float
:
left
;
line-height
:
20px
;
line-height
:
20px
;
margin
:
20px
;
margin
:
20px
;
padding
:
10px
20px
20px
;
padding
:
10px
20px
20px
;
width
:
393px
;
width
:
393px
;
}
}
.dynamic
.module
:hover
{
.dynamic
.module
:hover
{
box-shadow
:
0
0
4px
#D5D5D5
;
box-shadow
:
0
0
4px
#D5D5D5
;
}
}
.dynamic
.side-comments
{
.dynamic
.side-comments
{
width
:
600px
;
width
:
600px
;
}
}
.dynamic
.side-comments
.comment-panel
{
.dynamic
.side-comments
.comment-panel
{
width
:
510px
;
width
:
510px
;
}
}
.dynamic
.side-tags
{
.dynamic
.side-tags
{
width
:
186px
;
width
:
186px
;
}
}
.dynamic
.side-tags
li
{
.dynamic
.side-tags
li
{
float
:
left
;
float
:
left
;
margin
:
0
5px
;
margin
:
0
5px
;
}
}
/* end dynamic */
/* end dynamic */
/* start links */
/* start links */
.links
li
{
.links
li
{
float
:
left
;
float
:
left
;
margin
:
0
20px
10px
;
margin
:
0
20px
10px
;
width
:
273px
;
width
:
273px
;
}
}
/* end links */
/* end links */
/* start not list */
/* start not list */
.other-main
{
.other-main
{
display
:
inline-block
;
display
:
inline-block
;
margin
:
50px
20px
0
;
margin
:
50px
20px
0
;
width
:
950px
;
width
:
950px
;
}
}
/* end not list */
/* end not list */
\ No newline at end of file
war/src/main/webapp/skins/ease/css/ease.min.css
View file @
65f8a5e9
html
,
body
,
div
,
ul
,
li
{
margin
:
0
;
padding
:
0
;}
html
,
body
,
div
,
ul
,
li
{
margin
:
0
;
padding
:
0
;}
body
{
font-family
:
Verdana
,
arial
,
\
5
fae
\
8
f6f
\
96
c5
\
9
ed1
;
font-size
:
12px
;}
body
{
font-family
:
Verdana
,
arial
,
\
5
fae
\
8
f6f
\
96
c5
\
9
ed1
;
font-size
:
12px
;}
a
{
outline
:
none
;
color
:
#009EB8
;
text-decoration
:
none
;}
a
{
outline
:
none
;
color
:
#009EB8
;
text-decoration
:
none
;}
a
:visited
{
color
:
#00b4d2
;}
a
:visited
{
color
:
#00b4d2
;}
a
:hover
{
text-decoration
:
underline
;}
a
:hover
{
text-decoration
:
underline
;}
a
:active
{
color
:
#00889f
;}
a
:active
{
color
:
#00889f
;}
img
{
vertical-align
:
middle
;
border
:
0
;}
img
{
vertical-align
:
middle
;
border
:
0
;}
textarea
,
input
{
outline
:
none
;}
textarea
,
input
{
outline
:
none
;}
sup
{
font-size
:
10px
;
font-weight
:
normal
;
-webkit-text-size-adjust
:
none
;}
sup
{
font-size
:
10px
;
font-weight
:
normal
;
-webkit-text-size-adjust
:
none
;}
.left
{
float
:
left
;}
.left
{
float
:
left
;}
.right
{
float
:
right
;}
.right
{
float
:
right
;}
.clear
{
background-color
:
transparent
;
border
:
0
;
clear
:
both
;
display
:
block
;
font-size
:
0
;
height
:
0
;
line-height
:
0
;
overflow
:
hidden
;}
.clear
{
background-color
:
transparent
;
border
:
0
;
clear
:
both
;
display
:
block
;
font-size
:
0
;
height
:
0
;
line-height
:
0
;
overflow
:
hidden
;}
.none
{
display
:
none
;}
.none
{
display
:
none
;}
.ft-gray
{
color
:
#808080
;}
.ft-gray
{
color
:
#808080
;}
.ft-gray
:visited
{
color
:
#9a9a9a
;}
.ft-gray
:visited
{
color
:
#9a9a9a
;}
.ft-gray
:hover
{
color
:
#676767
;
text-decoration
:
none
;}
.ft-gray
:hover
{
color
:
#676767
;
text-decoration
:
none
;}
.logo
{
padding
:
0
5px
;
text-shadow
:
0
0
1px
#D5D5D5
;}
.logo
{
padding
:
0
5px
;
text-shadow
:
0
0
1px
#D5D5D5
;}
.em00
,
.em01
,
.em02
,
.em03
,
.em04
,
.em05
,
.em06
,
.em07
,
.em08
,
.em09
,
.em10
,
.em11
,
.em12
,
.em13
,
.em14
{
cursor
:
pointer
;
background-image
:
url(../../ease/images/emotions/emotions-ease.png)
;
float
:
left
;
height
:
24px
;
margin-right
:
5px
;
width
:
24px
;
transition
:
all
.2s
ease-out
;
-webkit-transition
:
all
.2s
ease-out
;
-moz-transition
:
all
.2s
ease-out
;}
.em00
,
.em01
,
.em02
,
.em03
,
.em04
,
.em05
,
.em06
,
.em07
,
.em08
,
.em09
,
.em10
,
.em11
,
.em12
,
.em13
,
.em14
{
cursor
:
pointer
;
background-image
:
url(../../ease/images/emotions/emotions-ease.png)
;
float
:
left
;
height
:
24px
;
margin-right
:
5px
;
width
:
24px
;
transition
:
all
.2s
ease-out
;
-webkit-transition
:
all
.2s
ease-out
;
-moz-transition
:
all
.2s
ease-out
;}
#emotions
span
:hover
{
transform
:
scale
(
1.2
)
rotate
(
360deg
);
-webkit-transform
:
scale
(
1.2
)
rotate
(
360deg
);
-moz-transform
:
scale
(
1.2
)
rotate
(
360deg
);}
#emotions
span
:hover
{
transform
:
scale
(
1.2
)
rotate
(
360deg
);
-webkit-transform
:
scale
(
1.2
)
rotate
(
360deg
);
-moz-transform
:
scale
(
1.2
)
rotate
(
360deg
);}
.em01
{
background-position
:
-24px
0
;}
.em01
{
background-position
:
-24px
0
;}
.em02
{
background-position
:
-48px
0
;}
.em02
{
background-position
:
-48px
0
;}
.em03
{
background-position
:
-72px
0
;}
.em03
{
background-position
:
-72px
0
;}
.em04
{
background-position
:
-96px
1px
;}
.em04
{
background-position
:
-96px
1px
;}
.em05
{
background-position
:
0
-24px
;}
.em05
{
background-position
:
0
-24px
;}
.em06
{
background-position
:
-24px
-24px
;}
.em06
{
background-position
:
-24px
-24px
;}
.em07
{
background-position
:
-48px
-24px
;}
.em07
{
background-position
:
-48px
-24px
;}
.em08
{
background-position
:
-72px
-24px
;}
.em08
{
background-position
:
-72px
-24px
;}
.em09
{
background-position
:
-96px
-24px
;}
.em09
{
background-position
:
-96px
-24px
;}
.em10
{
background-position
:
0
-48px
;}
.em10
{
background-position
:
0
-48px
;}
.em11
{
background-position
:
-24px
-48px
;}
.em11
{
background-position
:
-24px
-48px
;}
.em12
{
background-position
:
-48px
-48px
;}
.em12
{
background-position
:
-48px
-48px
;}
.em13
{
background-position
:
-72px
-48px
;}
.em13
{
background-position
:
-72px
-48px
;}
.em14
{
background-position
:
-96px
-48px
;}
.em14
{
background-position
:
-96px
-48px
;}
#search
,
.translate-ico
{
background-image
:
url(/skins/ease/images/icons.png)
;}
#search
,
.translate-ico
{
background-image
:
url(/skins/ease/images/icons.png)
;}
.translate-ico
{
background-position
:
1px
-125px
;
background-repeat
:
no-repeat
;
border
:
1px
solid
#D5D5D5
;
border-radius
:
3px
;
cursor
:
pointer
;
float
:
right
;
height
:
16px
;
margin
:
-3px
0
0
15px
;
padding
:
1px
;
width
:
16px
;}
.translate-ico
{
background-position
:
1px
-125px
;
background-repeat
:
no-repeat
;
border
:
1px
solid
#D5D5D5
;
border-radius
:
3px
;
cursor
:
pointer
;
float
:
right
;
height
:
16px
;
margin
:
-3px
0
0
15px
;
padding
:
1px
;
width
:
16px
;}
.translate-ico
:hover
{
border-color
:
#9a9a9a
;
box-shadow
:
0
0
1px
#808080
;
background-color
:
#FCFCFC
;}
.translate-ico
:hover
{
border-color
:
#9a9a9a
;
box-shadow
:
0
0
1px
#808080
;
background-color
:
#FCFCFC
;}
.wrapper
{
margin
:
0
50px
;}
.wrapper
{
margin
:
0
50px
;}
.body
{
margin
:
0
auto
50px
;
width
:
990px
;}
.body
{
margin
:
0
auto
50px
;
width
:
990px
;}
.header
{
width
:
100%
;
background-color
:
#FCFCFC
;
z-index
:
1
;}
.header
{
width
:
100%
;
background-color
:
#FCFCFC
;
z-index
:
1
;}
.header
.title
{
border-bottom
:
1px
solid
#808080
;
font-size
:
26px
;
font-weight
:
normal
;}
.header
.title
{
border-bottom
:
1px
solid
#808080
;
font-size
:
26px
;
font-weight
:
normal
;}
.header
.sub-title
{
font-size
:
11px
;}
.header
.sub-title
{
font-size
:
11px
;}
#search
{
background-position
:
7px
-99px
;
background-repeat
:
no-repeat
;
background-color
:
#FFF
;
border
:
1px
solid
#D5D5D5
;
border-radius
:
2px
2px
2px
2px
;
box-shadow
:
0
1px
1px
rgba
(
0
,
0
,
0
,
0.1
)
inset
;
color
:
#808080
;
float
:
right
;
font-size
:
14px
;
height
:
19px
;
line-height
:
145%
;
padding
:
4px
10px
4px
28px
;
width
:
24px
;
-moz-transition
:
width
.4s
ease
,
background
.4s
ease
;
-webkit-transition
:
width
.4s
ease
,
background
.4s
ease
;
transition
:
width
.4s
ease
,
background
.4s
ease
;}
#search
{
background-position
:
7px
-99px
;
background-repeat
:
no-repeat
;
background-color
:
#FFF
;
border
:
1px
solid
#D5D5D5
;
border-radius
:
2px
2px
2px
2px
;
box-shadow
:
0
1px
1px
rgba
(
0
,
0
,
0
,
0.1
)
inset
;
color
:
#808080
;
float
:
right
;
font-size
:
14px
;
height
:
19px
;
line-height
:
145%
;
padding
:
4px
10px
4px
28px
;
width
:
24px
;
-moz-transition
:
width
.4s
ease
,
background
.4s
ease
;
-webkit-transition
:
width
.4s
ease
,
background
.4s
ease
;
transition
:
width
.4s
ease
,
background
.4s
ease
;}
#search
:focus
{
background-color
:
#FCFCFC
;
width
:
196px
;}
#search
:focus
{
background-color
:
#FCFCFC
;
width
:
196px
;}
.banner
{
margin-bottom
:
20px
;}
.banner
{
margin-bottom
:
20px
;}
.banner
.notice
{
float
:
left
;
margin
:
20px
0
0
50px
;}
.banner
.notice
{
float
:
left
;
margin
:
20px
0
0
50px
;}
.nav
{
background-color
:
#2C2C2C
;
box-shadow
:
0
2px
2px
#D5D5D5
,
0
3px
3px
-3px
#D5D5D5
inset
;
height
:
29px
;
top
:
0
;
width
:
100%
;}
.nav
{
background-color
:
#2C2C2C
;
box-shadow
:
0
2px
2px
#D5D5D5
,
0
3px
3px
-3px
#D5D5D5
inset
;
height
:
29px
;
top
:
0
;
width
:
100%
;}
.nav
ul
{
list-style
:
none
;
float
:
left
;}
.nav
ul
{
list-style
:
none
;
float
:
left
;}
.nav
li
{
float
:
left
;}
.nav
li
{
float
:
left
;}
.nav
a
{
color
:
#C9C9C9
;
display
:
block
;
float
:
left
;
font-size
:
14px
;
font-weight
:
700
;
line-height
:
29px
;
margin-right
:
20px
;
padding
:
0
10px
;
text-decoration
:
none
;
transition
:
color
.4s
ease
,
background-color
.8s
ease
;
-webkit-transition
:
color
.4s
ease
,
background-color
.8s
ease
;
-moz-transition
:
color
.4s
ease
,
background-color
.8s
ease
;}
.nav
a
{
color
:
#C9C9C9
;
display
:
block
;
float
:
left
;
font-size
:
14px
;
font-weight
:
700
;
line-height
:
29px
;
margin-right
:
20px
;
padding
:
0
10px
;
text-decoration
:
none
;
transition
:
color
.4s
ease
,
background-color
.8s
ease
;
-webkit-transition
:
color
.4s
ease
,
background-color
.8s
ease
;
-moz-transition
:
color
.4s
ease
,
background-color
.8s
ease
;}
.nav
a
:hover
{
color
:
#FFF
;
background-color
:
#535353
;}
.nav
a
:hover
{
color
:
#FFF
;
background-color
:
#535353
;}
.nav
a
.current
{
background-color
:
#FFF
;
box-shadow
:
0
-1px
1px
rgba
(
0
,
0
,
0
,
0.1
)
inset
,
0
1px
1px
rgba
(
0
,
0
,
0
,
0.1
)
inset
;
color
:
#808080
;}
.nav
a
.current
{
background-color
:
#FFF
;
box-shadow
:
0
-1px
1px
rgba
(
0
,
0
,
0
,
0.1
)
inset
,
0
1px
1px
rgba
(
0
,
0
,
0
,
0.1
)
inset
;
color
:
#808080
;}
.nav
img
{
margin-left
:
3px
;}
.nav
img
{
margin-left
:
3px
;}
.footer
{
background-color
:
#FCFCFC
;
border-top
:
2px
solid
#D5D5D5
;
font-size
:
11px
;
padding
:
12px
0
;
-webkit-text-size-adjust
:
none
;}
.footer
{
background-color
:
#FCFCFC
;
border-top
:
2px
solid
#D5D5D5
;
font-size
:
11px
;
padding
:
12px
0
;
-webkit-text-size-adjust
:
none
;}
#goTop
{
background
:
url(/skins/ease/images/icons.png)
no-repeat
scroll
5px
-51px
#D5D5D5
;
border-radius
:
2px
2px
0
0
;
cursor
:
pointer
;
font-size
:
11px
;
height
:
21px
;
line-height
:
21px
;
padding
:
0
10px
0
23px
;
position
:
absolute
;
right
:
50px
;
display
:
none
;}
#goTop
{
background
:
url(/skins/ease/images/icons.png)
no-repeat
scroll
5px
-51px
#D5D5D5
;
border-radius
:
2px
2px
0
0
;
cursor
:
pointer
;
font-size
:
11px
;
height
:
21px
;
line-height
:
21px
;
padding
:
0
10px
0
23px
;
position
:
absolute
;
right
:
50px
;
display
:
none
;}
#goTop
:hover
{
background-color
:
#D5D5D5
;}
#goTop
:hover
{
background-color
:
#D5D5D5
;}
.body
>
ul
{
list-style
:
none
;}
.body
>
ul
{
list-style
:
none
;}
.article
{
border-bottom
:
1px
solid
#f6f6f6
;
padding
:
20px
70px
;}
.article
{
border-bottom
:
1px
solid
#f6f6f6
;
padding
:
20px
70px
;}
.article
:hover
{
border-bottom-color
:
#D5D5D5
;
box-shadow
:
0
0
1px
#f6f6f6
inset
;
background-color
:
#FCFCFC
;}
.article
:hover
{
border-bottom-color
:
#D5D5D5
;
box-shadow
:
0
0
1px
#f6f6f6
inset
;
background-color
:
#FCFCFC
;}
.article-body
{
line-height
:
145%
;
overflow
:
hidden
;
word-wrap
:
break-word
;}
.article-body
{
line-height
:
145%
;
overflow
:
hidden
;
word-wrap
:
break-word
;}
.article-body
ol
,
.article-body
ul
{
margin-left
:
40px
;}
.article-body
ol
,
.article-body
ul
{
margin-left
:
40px
;}
.article-body
a
{
color
:
#808080
;
text-decoration
:
underline
;}
.article-body
a
{
color
:
#808080
;
text-decoration
:
underline
;}
.article-body
a
:vidited
{
color
:
#9a9a9a
;}
.article-body
a
:vidited
{
color
:
#9a9a9a
;}
.article-body
a
:hover
{
color
:
#676767
;}
.article-body
a
:hover
{
color
:
#676767
;}
.article-body
>
div
{
min-height
:
32px
;}
.article-body
>
div
{
min-height
:
32px
;}
.article-title
h2
{
display
:
inline
;}
.article-title
h2
{
display
:
inline
;}
.article-title
span
{
cursor
:
pointer
;}
.article-title
span
{
cursor
:
pointer
;}
.article-next
{
background-color
:
#FCFCFC
;
box-shadow
:
0
0
3px
#D5D5D5
inset
;
cursor
:
pointer
;
font-size
:
14px
;
line-height
:
36px
;
text-align
:
center
;}
.article-next
{
background-color
:
#FCFCFC
;
box-shadow
:
0
0
3px
#D5D5D5
inset
;
cursor
:
pointer
;
font-size
:
14px
;
line-height
:
36px
;
text-align
:
center
;}
.article-next
:hover
{
box-shadow
:
0
0
3px
#D5D5D5
,
0
0
3px
#D5D5D5
inset
;}
.article-next
:hover
{
box-shadow
:
0
0
3px
#D5D5D5
,
0
0
3px
#D5D5D5
inset
;}
.article-relative
{
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
float
:
left
;
margin
:
20px
0
;
padding
:
0
20px
10px
;
width
:
365px
;}
.article-relative
{
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
float
:
left
;
margin
:
20px
0
;
padding
:
0
20px
10px
;
width
:
365px
;}
.article-relative
:hover
{
background-color
:
#fff
;
box-shadow
:
0
0
4px
#D5D5D5
;}
.article-relative
:hover
{
background-color
:
#fff
;
box-shadow
:
0
0
4px
#D5D5D5
;}
.article-relative
ul
{
list-style
:
none
;}
.article-relative
ul
{
list-style
:
none
;}
#relevantArticles
{
margin-right
:
40px
;}
#relevantArticles
{
margin-right
:
40px
;}
#externalRelevantArticles
{
width
:
297px
;
margin-top
:
0
;}
#externalRelevantArticles
{
width
:
297px
;
margin-top
:
0
;}
#comments
{
padding
:
20px
70px
;
position
:
relative
;}
#comments
{
padding
:
20px
70px
;
position
:
relative
;}
.comment-header
{
float
:
left
;
background-color
:
#FFF
;
border
:
1px
solid
#DEDEDE
;
padding
:
2px
;
height
:
60px
;
width
:
60px
;}
.comment-header
{
float
:
left
;
background-color
:
#FFF
;
border
:
1px
solid
#DEDEDE
;
padding
:
2px
;
height
:
60px
;
width
:
60px
;}
.comment-panel
{
float
:
left
;
line-height
:
16px
;
margin
:
0
10px
20px
;
min-height
:
64px
;
overflow
:
hidden
;
width
:
760px
;}
.comment-panel
{
float
:
left
;
line-height
:
16px
;
margin
:
0
10px
20px
;
min-height
:
64px
;
overflow
:
hidden
;
width
:
760px
;}
.comment-body-ref
{
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
display
:
block
;
left
:
140px
;
padding
:
10px
;
opacity
:
0.9
;
filter
:
alpha
(
opacity
=
90
);
position
:
absolute
;}
.comment-body-ref
{
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
display
:
block
;
left
:
140px
;
padding
:
10px
;
opacity
:
0.9
;
filter
:
alpha
(
opacity
=
90
);
position
:
absolute
;}
.comment-body-ref
>
.comment-header
{
border
:
0
none
;
float
:
right
;
height
:
48px
;
width
:
48px
;
padding
:
0
;}
.comment-body-ref
>
.comment-header
{
border
:
0
none
;
float
:
right
;
height
:
48px
;
width
:
48px
;
padding
:
0
;}
.comment-body-ref
>
.comment-panel
{
margin
:
0
20px
0
0
;
min-height
:
48px
;
width
:
756px
;}
.comment-body-ref
>
.comment-panel
{
margin
:
0
20px
0
0
;
min-height
:
48px
;
width
:
756px
;}
.form
{
padding
:
0
70px
20px
;
float
:
left
;}
.form
{
padding
:
0
70px
20px
;
float
:
left
;}
.form
th
{
text-align
:
right
;
white-space
:
nowrap
;}
.form
th
{
text-align
:
right
;
white-space
:
nowrap
;}
.form
input
[
type
=
text
],
.form
input
[
type
=
password
],
.form
textarea
{
background-color
:
#FCFCFC
;
border-width
:
0
;
box-shadow
:
0
0
2px
#BCBCBC
;
font-family
:
Verdana
,
arial
,
\
5
fae
\
8
f6f
\
96
c5
\
9
ed1
;
font-size
:
12px
;
margin
:
0
5px
10px
0
;
outline
:
medium
none
;
padding
:
0
3px
;
height
:
28px
;
line-height
:
28px
;
width
:
260px
;}
.form
input
[
type
=
text
],
.form
input
[
type
=
password
],
.form
textarea
{
background-color
:
#FCFCFC
;
border-width
:
0
;
box-shadow
:
0
0
2px
#BCBCBC
;
font-family
:
Verdana
,
arial
,
\
5
fae
\
8
f6f
\
96
c5
\
9
ed1
;
font-size
:
12px
;
margin
:
0
5px
10px
0
;
outline
:
medium
none
;
padding
:
0
3px
;
height
:
28px
;
line-height
:
28px
;
width
:
260px
;}
.form
input
:focus
,
.form
textarea
:focus
{
box-shadow
:
0
0
4px
#D5D5D5
;}
.form
input
:focus
,
.form
textarea
:focus
{
box-shadow
:
0
0
4px
#D5D5D5
;}
.form
textarea
{
height
:
120px
;
overflow
:
auto
;
width
:
426px
;
line-height
:
16px
;}
.form
textarea
{
height
:
120px
;
overflow
:
auto
;
width
:
426px
;
line-height
:
16px
;}
.form
button
{
background-color
:
#F6F6F6
;
border
:
0
none
;
box-shadow
:
0
0
2px
#D5D5D5
;
height
:
28px
;
line-height
:
28px
;
padding
:
0
12px
;
color
:
#A7A7A7
;}
.form
button
{
background-color
:
#F6F6F6
;
border
:
0
none
;
box-shadow
:
0
0
2px
#D5D5D5
;
height
:
28px
;
line-height
:
28px
;
padding
:
0
12px
;
color
:
#A7A7A7
;}
.form
button
:hover
{
box-shadow
:
0
0
4px
#D5D5D5
;
text-shadow
:
0
0
2px
;}
.form
button
:hover
{
box-shadow
:
0
0
4px
#D5D5D5
;
text-shadow
:
0
0
2px
;}
.form
img
{
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
cursor
:
pointer
;
height
:
24px
;
padding
:
1px
;}
.form
img
{
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
cursor
:
pointer
;
height
:
24px
;
padding
:
1px
;}
#tags
li
{
float
:
left
;
height
:
38px
;}
#tags
li
{
float
:
left
;
height
:
38px
;}
#tags
a
{
margin
:
3px
6px
;
padding
:
3px
12px
;
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
float
:
left
;}
#tags
a
{
margin
:
3px
6px
;
padding
:
3px
12px
;
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
float
:
left
;}
#tags
a
:hover
{
text-shadow
:
0
0
2px
;
text-decoration
:
none
;
box-shadow
:
0
0
4px
#D5D5D5
;}
#tags
a
:hover
{
text-shadow
:
0
0
2px
;
text-decoration
:
none
;
box-shadow
:
0
0
4px
#D5D5D5
;}
.tags1
,
.tags1
:visited
{
font-size
:
12px
;
color
:
#a7a7a7
;}
.tags1
,
.tags1
:visited
{
font-size
:
12px
;
color
:
#a7a7a7
;}
.tags2
,
.tags2
:visited
{
font-size
:
14px
;
color
:
#808080
;}
.tags2
,
.tags2
:visited
{
font-size
:
14px
;
color
:
#808080
;}
.tags3
,
.tags3
:visited
{
font-size
:
16px
;
color
:
#595959
;}
.tags3
,
.tags3
:visited
{
font-size
:
16px
;
color
:
#595959
;}
.tags4
,
.tags4
:visited
{
font-size
:
18px
;
color
:
#323232
;}
.tags4
,
.tags4
:visited
{
font-size
:
18px
;
color
:
#323232
;}
.tags5
,
.tags5
:visited
{
font-size
:
20px
;
color
:
#0a0a0a
;}
.tags5
,
.tags5
:visited
{
font-size
:
20px
;
color
:
#0a0a0a
;}
.archives
{
position
:
relative
;}
.archives
{
position
:
relative
;}
.archives
>
div
{
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
padding-bottom
:
20px
;
line-height
:
20px
;
margin
:
20px
;
width
:
276px
;
position
:
absolute
;
top
:
0
;}
.archives
>
div
{
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
padding-bottom
:
20px
;
line-height
:
20px
;
margin
:
20px
;
width
:
276px
;
position
:
absolute
;
top
:
0
;}
.archives
h3
{
text-align
:
center
;}
.archives
h3
{
text-align
:
center
;}
.archives
>
div
:hover
{
box-shadow
:
0
0
4px
#D5D5D5
;}
.archives
>
div
:hover
{
box-shadow
:
0
0
4px
#D5D5D5
;}
.archives
a
{
display
:
block
;
margin-left
:
80px
;}
.archives
a
{
display
:
block
;
margin-left
:
80px
;}
.dynamic
ul
{
list-style
:
none
;}
.dynamic
ul
{
list-style
:
none
;}
.dynamic
h3
{
text-align
:
center
;}
.dynamic
h3
{
text-align
:
center
;}
.dynamic
.module
{
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
float
:
left
;
line-height
:
20px
;
margin
:
20px
;
padding
:
10px
20px
20px
;
width
:
393px
;}
.dynamic
.module
{
background-color
:
#FCFCFC
;
box-shadow
:
0
0
2px
#D5D5D5
;
float
:
left
;
line-height
:
20px
;
margin
:
20px
;
padding
:
10px
20px
20px
;
width
:
393px
;}
.dynamic
.module
:hover
{
box-shadow
:
0
0
4px
#D5D5D5
;}
.dynamic
.module
:hover
{
box-shadow
:
0
0
4px
#D5D5D5
;}
.dynamic
.side-comments
{
width
:
600px
;}
.dynamic
.side-comments
{
width
:
600px
;}
.dynamic
.side-comments
.comment-panel
{
width
:
510px
;}
.dynamic
.side-comments
.comment-panel
{
width
:
510px
;}
.dynamic
.side-tags
{
width
:
186px
;}
.dynamic
.side-tags
{
width
:
186px
;}
.dynamic
.side-tags
li
{
float
:
left
;
margin
:
0
5px
;}
.dynamic
.side-tags
li
{
float
:
left
;
margin
:
0
5px
;}
.links
li
{
float
:
left
;
margin
:
0
20px
10px
;
width
:
273px
;}
.links
li
{
float
:
left
;
margin
:
0
20px
10px
;
width
:
273px
;}
.other-main
{
display
:
inline-block
;
margin
:
50px
20px
0
;
width
:
950px
;}
.other-main
{
display
:
inline-block
;
margin
:
50px
20px
0
;
width
:
950px
;}
\ No newline at end of file
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