PageRenderTime 572ms CodeModel.GetById 38ms RepoModel.GetById 0ms app.codeStats 0ms

/wolfengine-core/src/main/java/com/sfeir/wolfengine/server/servlet/renderer/impl/StoryHtmlRenderer.java

http://wolfengine.googlecode.com/
Java | 661 lines | 519 code | 64 blank | 78 comment | 118 complexity | 1fbcf2bbc3ade1772c5e4643f4354fd0 MD5 | raw file
Possible License(s): CC0-1.0
  1. package com.sfeir.wolfengine.server.servlet.renderer.impl;
  2. import java.io.IOException;
  3. import java.text.SimpleDateFormat;
  4. import java.util.ArrayList;
  5. import java.util.Collections;
  6. import java.util.List;
  7. import java.util.ListIterator;
  8. import java.util.Random;
  9. import org.apache.commons.logging.Log;
  10. import org.apache.commons.logging.LogFactory;
  11. import com.google.appengine.api.datastore.Key;
  12. import com.google.appengine.api.datastore.KeyFactory;
  13. import com.google.appengine.api.users.User;
  14. import com.google.appengine.api.users.UserServiceFactory;
  15. import com.google.inject.Guice;
  16. import com.google.inject.Inject;
  17. import com.google.inject.Injector;
  18. import com.google.inject.name.Named;
  19. import com.sfeir.wolfengine.client.model.entity.SearchResult;
  20. import com.sfeir.wolfengine.server.entity.Story;
  21. import com.sfeir.wolfengine.server.entity.datamanagement.Category;
  22. import com.sfeir.wolfengine.server.entity.datamanagement.Comment;
  23. import com.sfeir.wolfengine.server.entity.datamanagement.HitsLink;
  24. import com.sfeir.wolfengine.server.entity.datamanagement.HitsTag;
  25. import com.sfeir.wolfengine.server.guice.WolfEngineModule;
  26. import com.sfeir.wolfengine.server.servlet.model.StoryModel;
  27. /**
  28. * This class implements the HTML rendering of BlogPost objects.
  29. *
  30. * @author Sfeir
  31. */
  32. public class StoryHtmlRenderer extends HtmlRenderer<StoryModel> {
  33. public static class PostMessages extends Messages {
  34. @Inject
  35. @Named("message.allTags")
  36. public String allTags;
  37. @Inject
  38. @Named("message.categories")
  39. public String categories;
  40. @Inject
  41. @Named("message.comments")
  42. public String comments;
  43. @Inject
  44. @Named("message.email")
  45. public String email;
  46. @Inject
  47. @Named("message.feedRss")
  48. public String feedRss;
  49. @Inject
  50. @Named("message.feedRssInfo")
  51. public String feedRssInfo;
  52. @Inject
  53. @Named("message.htmlAndEmailMessageInfo")
  54. public String htmlAndEmailMessageInfo;
  55. @Inject
  56. @Named("message.links")
  57. public String links;
  58. @Inject
  59. @Named("message.listLinks")
  60. public String listLinks;
  61. @Inject
  62. @Named("message.logoImage")
  63. public String logoImage;
  64. @Inject
  65. @Named("message.logoUrl")
  66. public String logoUrl;
  67. @Inject
  68. @Named("message.next")
  69. public String next;
  70. @Inject
  71. @Named("message.noComment")
  72. public String noComment;
  73. @Inject
  74. @Named("message.noContent")
  75. public String noContent;
  76. @Inject
  77. @Named("message.oneComment")
  78. public String oneComment;
  79. @Inject
  80. @Named("message.prev")
  81. public String prev;
  82. @Inject
  83. @Named("message.propulsed")
  84. public String propulsed;
  85. @Inject
  86. @Named("message.pseudo")
  87. public String pseudo;
  88. @Inject
  89. @Named("message.syndication")
  90. public String syndication;
  91. @Inject
  92. @Named("message.tags")
  93. public String tags;
  94. @Inject
  95. @Named("message.unknownDate")
  96. public String unknownDate;
  97. @Inject
  98. @Named("message.website")
  99. public String website;
  100. @Inject
  101. @Named("message.send")
  102. public String send;
  103. @Inject
  104. @Named("message.addComment")
  105. public String addComment;
  106. @Inject
  107. @Named("message.starredstories")
  108. public String starredstories;
  109. }
  110. private static Log log = LogFactory.getLog(StoryHtmlRenderer.class);
  111. // Date formatter used to created dates like : Lundi 10 d?Šcembre 2006
  112. private SimpleDateFormat sdf = new SimpleDateFormat("EEEEEE dd MMMM yyyy");
  113. // Date formatter used to created dates like : Lundi 10 d?Šcembre 2006 12:56
  114. private SimpleDateFormat sdfWithHour = new SimpleDateFormat("EEEEEE dd MMMM yyyy hh:mm");
  115. // StringBuilder used to store HtmlContent to display
  116. private StringBuilder stringBuilder;
  117. protected void buildCategories(List<Category> categories) {
  118. stringBuilder.append("<div class=\"categories\"><h2>");
  119. stringBuilder.append(getMessage().categories);
  120. stringBuilder.append("</h2><ul>");
  121. for (Category category : categories) {
  122. stringBuilder.append("<li><a href=\"");
  123. stringBuilder.append(getMessage().CATEGORY_URL.replace("{NAME}", category.getUrl()));
  124. stringBuilder.append("\">");
  125. stringBuilder.append(category.getName());
  126. stringBuilder.append("</a></li>");
  127. }
  128. stringBuilder.append("</ul></div>");
  129. }
  130. protected void buildStarredStories(SearchResult<Story> searchResult) {
  131. stringBuilder.append("<div class=\"starredstories\"><h2>");
  132. stringBuilder.append(getMessage().starredstories);
  133. stringBuilder.append("</h2><ul>");
  134. for (Story story : searchResult.getItems()) {
  135. stringBuilder.append("<li><a href=\"");
  136. stringBuilder.append(getMessage().POST_URL + story.getUrl());
  137. stringBuilder.append("\">");
  138. stringBuilder.append(story.getTitle());
  139. stringBuilder.append("</a></li>");
  140. }
  141. stringBuilder.append("</ul></div>");
  142. }
  143. private void buildFooter(StoryModel model) {
  144. stringBuilder.append("</div></div><div id=\"sidebar\"><div id=\"blognav\"><div class=\"text\"><a href=\"");
  145. stringBuilder.append(getMessage().logoUrl);
  146. stringBuilder.append("\"><img src=\"");
  147. stringBuilder.append(getMessage().logoImage);
  148. stringBuilder.append("\" /></a></div><div id=\"topnav\"><ul></ul></div>");
  149. buildTags(model.getTags());
  150. buildCategories(model.getCategories());
  151. buildStarredStories(model.getStarredSories());
  152. stringBuilder.append("</div><div id=\"blogextra\"><div class=\"syndicate\"><h2>");
  153. stringBuilder.append(getMessage().syndication);
  154. stringBuilder.append("</h2><ul><li><a type=\"application/rss+xml\" href=\"");
  155. stringBuilder.append(getMessage().FEED_URL);
  156. stringBuilder.append("\" title=\"");
  157. stringBuilder.append(getMessage().feedRssInfo);
  158. stringBuilder.append("\" class=\"feed\">");
  159. stringBuilder.append(getMessage().feedRss);
  160. stringBuilder.append("</a></li>");
  161. stringBuilder.append("</ul></div><div class=\"links\"><h2>");
  162. stringBuilder.append(getMessage().links);
  163. stringBuilder.append("</h2>");
  164. stringBuilder.append(getMessage().listLinks);
  165. stringBuilder.append("</div></div></div></div><div id=\"footer\"><p>");
  166. stringBuilder.append(getMessage().propulsed);
  167. stringBuilder.append("</p></div></div></body></html>");
  168. }
  169. private void buildHeader() {
  170. String result = "<html><head><title>"
  171. + this.title
  172. + "</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><style type=\"text/css\" media=\"print\">@import url(/ressource/css/print.css);</style><style type=\"text/css\">@import url(/ressource/css/custom_style.css);</style><link rel=\"alternate\" type=\"application/xml\" title=\"rss 2.0\" href=\"" + getMessage().FEED_URL + "\" /></head><body class=\"dc-home\"><div id=\"page\"><div id=\"top\"><h1><span><a href=\"" + getMessage().HOST_INDEX
  173. + "\">" + this.title + "</a></span></h1></div><p id=\"prelude\"><a href=\"#main\">"
  174. + getMessage().gotoContent + "</a> | <a href=\"#blognav\">" + getMessage().gotoMenu + "</a> | <a href=\"#search\">" + getMessage().gotoSearch
  175. + "</a></p><div id=\"wrapper\"><div id=\"main\"><div id=\"content\">";
  176. stringBuilder.insert(0, result); // To add the title
  177. }
  178. /**
  179. * Build a representation of the most used tags
  180. *
  181. * @param result
  182. * @param tags
  183. * @return Tags HTML representation
  184. */
  185. protected void buildTags(List<HitsTag> tags) {
  186. // Default max value
  187. long max = 100;
  188. if (tags != null && !tags.isEmpty() && tags.get(0).getHits() != null)
  189. max = tags.get(0).getHits();
  190. stringBuilder.append("<div class=\"content-inner\"><div class=\"tags\"><h2>");
  191. stringBuilder.append(getMessage().tags);
  192. stringBuilder.append("</h2><ul>");
  193. if (null == tags) {
  194. stringBuilder.append("<li>No tags</li>");
  195. } else {
  196. Long tagOccurency;
  197. Integer compteur = 0;
  198. ListIterator<HitsTag> iterator = tags.listIterator();
  199. while (iterator.hasNext() && compteur < 20) {
  200. HitsTag tag = iterator.next();
  201. compteur++;
  202. if (tag.getHits() != null)
  203. tagOccurency = ((tag.getHits().intValue() * 100) / max);
  204. else
  205. tagOccurency = 0l;
  206. stringBuilder.append("<li><a href=\"");
  207. stringBuilder.append(getMessage().TAG_URL.replace("{NAME}", tag.getName()));
  208. stringBuilder.append("\" class=\"tag");
  209. stringBuilder.append(getTagRate(tagOccurency));
  210. stringBuilder.append("\">");
  211. stringBuilder.append(tag.getName());
  212. stringBuilder.append("</a> </li>");
  213. }
  214. }
  215. stringBuilder.append("</ul><p><strong><a href=\"");
  216. stringBuilder.append(getMessage().TAGS_URL);
  217. stringBuilder.append("\">");
  218. stringBuilder.append(getMessage().allTags);
  219. stringBuilder.append("</a></strong></p></div></div>");
  220. }
  221. @Override
  222. protected PostMessages createMessages() {
  223. return new PostMessages();
  224. }
  225. /**
  226. * Return the content to display according to the view's context (list,
  227. * specific item, ...) Content is added to a global and shared StringBuilder
  228. * and returned at the end The StringBuilder's content is trashed at each
  229. * call
  230. */
  231. @Override
  232. protected String getHtmlRepresentation(StoryModel model) throws Exception {
  233. log.info("<StoryHtmlRenderer.getHtmlRepresentation>" + System.currentTimeMillis());
  234. // main content
  235. stringBuilder = new StringBuilder();
  236. // Display a list
  237. if (model.isMultiplePostMode()) {
  238. // Add the content of the posts list to the string Builder
  239. writeListOfPosts(model.getStories(), model);
  240. log.info("<StoryHtmlRenderer.getHtmlRepresentation.1>" + System.currentTimeMillis());
  241. // Add the pager to the String Builder according to the number of
  242. // posts
  243. writePagination(model);
  244. log.info("<StoryHtmlRenderer.getHtmlRepresentation.2>" + System.currentTimeMillis());
  245. }// Display a specific post
  246. else if (model.getViewMode().equals(StoryModel.PostViewModeEnum.DETAILED_MODE)) {
  247. // Get the post and add its html representation to the StringBuilder
  248. Story blogPostToDisplay = model.getStories().get(0);
  249. this.title += " - " + blogPostToDisplay.getTitle();
  250. log.info("<StoryHtmlRenderer.getHtmlRepresentation.3>" + System.currentTimeMillis());
  251. writeDetailedPost(blogPostToDisplay, model, false, true);
  252. log.info("<StoryHtmlRenderer.getHtmlRepresentation.4>" + System.currentTimeMillis());
  253. } else if (model.getViewMode().equals(StoryModel.PostViewModeEnum.TAGS)) {
  254. writeTagsCloud(model);
  255. } else
  256. throw new IllegalArgumentException("Bad view mode : " + model.getViewMode());
  257. // footer
  258. log.info("<StoryHtmlRenderer.getHtmlRepresentation.5>" + System.currentTimeMillis());
  259. buildFooter(model);
  260. buildHeader(); // To add the title after
  261. String result = stringBuilder.toString();
  262. log.info("</StoryHtmlRenderer.getHtmlRepresentation>" + System.currentTimeMillis());
  263. return result;
  264. }
  265. protected PostMessages getMessage() {
  266. if (messages == null) {
  267. messages = createMessages();
  268. Injector injector = Guice.createInjector(new WolfEngineModule(this));
  269. injector.injectMembers(messages);
  270. }
  271. return (PostMessages) messages;
  272. }
  273. /**
  274. * Method that return the size that the tag shoud be displayed with
  275. *
  276. * @param tagOccurency
  277. * @return font size value
  278. */
  279. private String getTagRate(Long tagOccurency) {
  280. String occurencyString = tagOccurency.toString().charAt(0) + "";
  281. if (tagOccurency < 10 && tagOccurency > 0)
  282. return "10";
  283. for (int i = 0; i < tagOccurency.toString().length() - 1; i++)
  284. occurencyString += 0;
  285. return occurencyString;
  286. }
  287. private String replaceLinks(String text) {
  288. text = text.replace("<", "&lt;").replace(">", "&gt;");
  289. return text.replaceAll("(http://\\S*)", "<a href=\"$1\" rel=\"nofollow\">$1</a>").replaceAll("\\n", "<br/>").replaceAll("(\\S*)@(\\S*)",
  290. "<a href=\"#\" onclick=\"window.location=[\'$2\',\'@\',\'$1\',\'://\',\'to\', \'mail\'].reverse().join(\'\'); return false;\" rel=\"nofollow\">$1[&#64;]$2</a>");
  291. }
  292. /**
  293. * Add the form to post comments to a post into the StringBuffer
  294. *
  295. * @param story
  296. */
  297. private void writeCommentsForm(Story story, StoryModel model) {
  298. Boolean areCommentsAllowed = true;
  299. if (model != null && model.getSetupInfo() != null) {
  300. areCommentsAllowed = model.areCommentsAllowed(story, model.getSetupInfo().getCommentsAllowedTime());
  301. } else {
  302. areCommentsAllowed = model.areCommentsAllowed(story, null);
  303. }
  304. if (areCommentsAllowed) {
  305. User user = UserServiceFactory.getUserService().getCurrentUser();
  306. Comment currComment = model.getCurrComment();
  307. if (model.getCommentError() != null) {
  308. stringBuilder.append("<p class=\"error\">" + model.getCommentError() + "</p>");
  309. }
  310. stringBuilder.append("<form action=\"" + getMessage().COMMENT_URL.replace("{POST_URL}", story.getUrl()) + "\" method=\"post\" id=\"comment-form\">");
  311. stringBuilder.append("<h3>");
  312. stringBuilder.append(getMessage().addComment);
  313. stringBuilder.append("</h3>");
  314. stringBuilder.append("<fieldset>");
  315. stringBuilder.append("<p class=\"field\"><label for=\"c_name\">");
  316. stringBuilder.append(getMessage().pseudo);
  317. stringBuilder.append("&nbsp;:</label>");
  318. stringBuilder.append("<input name=\"c_name\" id=\"c_name\" type=\"text\" size=\"30\" maxlength=\"255\" value=\"");
  319. if (currComment != null && currComment.getAlias() != null) {
  320. stringBuilder.append(currComment.getAlias());
  321. } else if (user != null) {
  322. stringBuilder.append(user.getNickname());
  323. }
  324. stringBuilder.append("\"/>");
  325. stringBuilder.append("</p>");
  326. stringBuilder.append("<p class=\"field\"><label for=\"c_mail\">");
  327. stringBuilder.append(getMessage().email);
  328. stringBuilder.append("&nbsp;:</label>");
  329. stringBuilder.append("<input name=\"c_mail\" id=\"c_mail\" type=\"text\" size=\"30\" maxlength=\"255\" value=\"");
  330. if (currComment != null && currComment.getEmail() != null) {
  331. stringBuilder.append(currComment.getEmail());
  332. } else if (user != null) {
  333. stringBuilder.append(user.getEmail());
  334. }
  335. stringBuilder.append("\" />");
  336. stringBuilder.append("</p>");
  337. stringBuilder.append("<p class=\"field\"><label for=\"c_site\">");
  338. stringBuilder.append(getMessage().website);
  339. stringBuilder.append("&nbsp;:</label>");
  340. stringBuilder.append("<input name=\"c_site\" id=\"c_site\" type=\"text\" size=\"30\" maxlength=\"255\" value=\"");
  341. if ((currComment != null && currComment.getWebSite() != null))
  342. stringBuilder.append(currComment.getWebSite());
  343. stringBuilder.append("\" />");
  344. stringBuilder.append("</p>");
  345. stringBuilder.append("<p style=\"display:none\"><input name=\"f_mail\" type=\"text\" size=\"30\" maxlength=\"255\" value=\"\" />");
  346. stringBuilder.append("</p>");
  347. stringBuilder.append("<p class=\"field\"><label for=\"c_content\">");
  348. stringBuilder.append(getMessage().comments);
  349. stringBuilder.append("&nbsp;:</label>");
  350. stringBuilder.append("<textarea name=\"c_content\" id=\"c_content\" cols=\"25\" rows=\"7\">");
  351. if (currComment != null && currComment.getContent() != null)
  352. stringBuilder.append(currComment.getContent());
  353. stringBuilder.append("</textarea>");
  354. stringBuilder.append("</p>");
  355. stringBuilder.append("<p class=\"form-help\">");
  356. stringBuilder.append(getMessage().htmlAndEmailMessageInfo);
  357. stringBuilder.append("</p></fieldset><fieldset>");
  358. stringBuilder.append("<p class=\"buttons\"><input type=\"submit\" class=\"preview\" name=\"preview\" value=\"");
  359. stringBuilder.append(getMessage().send);
  360. stringBuilder.append("\" />");
  361. stringBuilder.append("</p></fieldset></form>");
  362. }
  363. }
  364. /**
  365. * Write the content of a specific post
  366. *
  367. * @param story
  368. * @param headerView
  369. * @param first
  370. * TODO: -Refactor into some methods -Make it more readable
  371. */
  372. private void writeDetailedPost(Story story, StoryModel model, boolean headerView, boolean first) {
  373. log.info("<StoryHtmlRenderer.writeDetailedPost>" + System.currentTimeMillis());
  374. String cssClass;
  375. String dateAsString;
  376. String dateAsStringWithHour;
  377. if (first)
  378. cssClass = "post odd first";
  379. else
  380. cssClass = "post odd ";
  381. if (story.getPublishDate() != null) {
  382. dateAsString = sdf.format(story.getPublishDate());
  383. dateAsStringWithHour = sdfWithHour.format(story.getPublishDate());
  384. } else if (story.getCreationDate() != null) {
  385. dateAsString = sdf.format(story.getCreationDate());
  386. dateAsStringWithHour = sdfWithHour.format(story.getCreationDate());
  387. } else {
  388. dateAsString = getMessage().unknownDate;
  389. dateAsStringWithHour = getMessage().unknownDate;
  390. }
  391. log.info("<StoryHtmlRenderer.writeDetailedPost.1>" + System.currentTimeMillis());
  392. stringBuilder.append("<div class=\"").append(cssClass);
  393. stringBuilder.append("\" lang=\"fr\" xml:lang=\"fr\">");
  394. stringBuilder.append("<p class=\"day-date\">").append(dateAsString).append("</p>");
  395. stringBuilder.append("<h2 id=\"p312296\" class=\"post-title\">");
  396. stringBuilder.append("<a href=\"").append(getMessage().POST_URL).append(story.getUrl());
  397. stringBuilder.append("\">").append(story.getTitle()).append("</a>" + "</h2>");
  398. stringBuilder.append("<p class=\"post-info\">");
  399. log.info("<StoryHtmlRenderer.writeDetailedPost.2>" + System.currentTimeMillis());
  400. String author = null;
  401. if (story.getAuthors() != null)
  402. author = model.getAuthor(story.getAuthors().get(0));
  403. log.info("<StoryHtmlRenderer.writeDetailedPost.3>" + System.currentTimeMillis());
  404. if (author != null && !author.isEmpty())
  405. stringBuilder.append("Par " + author);
  406. stringBuilder.append(" le " + dateAsStringWithHour);
  407. log.info("<StoryHtmlRenderer.writeDetailedPost.4>" + System.currentTimeMillis());
  408. if (story.getCategory() != null) {
  409. Category category = model.getCategory(story.getCategory());
  410. if (category != null) {
  411. stringBuilder.append(" - <a href=\"" + getMessage().CATEGORY_URL.replace("{NAME}", category.getUrl()) + "\">");
  412. stringBuilder.append(category.getName() + "</a>");
  413. }
  414. }
  415. log.info("<StoryHtmlRenderer.writeDetailedPost.5>" + System.currentTimeMillis());
  416. stringBuilder.append("</p>" + "<ul class=\"post-tags\">");
  417. if (story.getTags() != null) {
  418. for (Key tag : story.getTags()) {
  419. String tagname = model.getTag(tag);
  420. if (tagname != null) {
  421. stringBuilder.append("<li><a href=\"" + getMessage().TAG_URL.replace("{NAME}", tagname) + "\">" + tagname + "</a></li>");
  422. }
  423. }
  424. }
  425. log.info("<StoryHtmlRenderer.writeDetailedPost.7>" + System.currentTimeMillis());
  426. stringBuilder.append("</ul>");
  427. stringBuilder.append("<div class=\"post-content\">");
  428. String content = "";
  429. if (story.getDescription() != null)
  430. content = story.getDescription();
  431. if (!headerView || content == null || "".equals(content.trim()))
  432. content += story.getContent();
  433. if (content != null)
  434. stringBuilder.append(content);
  435. else
  436. stringBuilder.append(getMessage().noContent);
  437. log.info("<StoryHtmlRenderer.writeDetailedPost.8>" + System.currentTimeMillis());
  438. // Affichage des liens
  439. if (story.getLinks() != null) {
  440. for (HitsLink link : story.getLinks()) {
  441. stringBuilder.append("<p><a title=\"");
  442. stringBuilder.append(link.getUrl().getValue());
  443. stringBuilder.append("\" href=\"");
  444. stringBuilder.append(getMessage().LINK_URL.replace("{KEY}", KeyFactory.keyToString(link.getKey())));
  445. stringBuilder.append("\">").append(link.getLabel()).append(" (").append(link.getHits().intValue()).append(" hits)</a><p>");
  446. }
  447. }
  448. log.info("<StoryHtmlRenderer.writeDetailedPost.9>" + System.currentTimeMillis());
  449. stringBuilder.append("<p class=\"post-info-co\">");
  450. if (headerView) {// On affiche le nombre de commentaires
  451. if (story.getComments() != null && !story.getComments().isEmpty()) {
  452. if (story.getComments().size() == 1) {
  453. stringBuilder.append("<a href=\"");
  454. stringBuilder.append(getMessage().POST_URL + story.getUrl());
  455. stringBuilder.append("#comments\" class=\"comment_count\">");
  456. stringBuilder.append(getMessage().oneComment);
  457. stringBuilder.append("</a>");
  458. } else {
  459. stringBuilder.append("<a href=\"");
  460. stringBuilder.append(getMessage().POST_URL + story.getUrl());
  461. stringBuilder.append("#comments\" class=\"comment_count\">");
  462. stringBuilder.append(story.getComments().size());
  463. stringBuilder.append(getMessage().comments);
  464. stringBuilder.append("</a>");
  465. }
  466. } else {
  467. stringBuilder.append("<a href=\"");
  468. stringBuilder.append(getMessage().POST_URL + story.getUrl());
  469. stringBuilder.append("#comments\" class=\"comment_count\">");
  470. stringBuilder.append(getMessage().next);
  471. stringBuilder.append("</a>");
  472. }
  473. stringBuilder.append("</p></div>");
  474. stringBuilder.append("</div>");
  475. } else {
  476. stringBuilder.append("</p></div>");
  477. stringBuilder.append("</div>");
  478. // On affiche la liste des commentaires
  479. if (story.getComments() != null && !story.getComments().isEmpty()) {
  480. writePostComments(story.getComments());
  481. }
  482. // On affiche le formulaire permettant de poster un commentaire
  483. writeCommentsForm(story, model);
  484. }
  485. log.info("</StoryHtmlRenderer.writeDetailedPost>" + System.currentTimeMillis());
  486. }
  487. /**
  488. * Write the content of a list of posts
  489. *
  490. * @param liste
  491. * post list
  492. * @throws IOException
  493. */
  494. private void writeListOfPosts(List<Story> liste, StoryModel model) throws IOException {
  495. for (Story blogPost : liste) {
  496. writeDetailedPost(blogPost, model, true, false);
  497. }
  498. }
  499. /**
  500. * Write the pagination panel
  501. *
  502. * @param model
  503. * post model
  504. */
  505. private void writePagination(StoryModel model) {
  506. // Ecriture de la pagination
  507. stringBuilder.append("<p class=\"pagination\">");
  508. if (!model.isOnLastPage()) {
  509. stringBuilder.append("<a href=\"").append(request.getRequestURI()).append("?p=");
  510. stringBuilder.append(model.getActualPage() + 1);
  511. stringBuilder.append("\" class=\"prev\">&#171; ");
  512. stringBuilder.append(getMessage().prev);
  513. stringBuilder.append("</a> - ");
  514. }
  515. stringBuilder.append("page ").append(model.getActualPage() + 1).append(" de ");
  516. stringBuilder.append(model.getNbPages());
  517. if (!model.isOnFirstPage()) {
  518. stringBuilder.append(" - <a href=\"").append(request.getRequestURI()).append("?p=");
  519. stringBuilder.append(model.getActualPage() - 1);
  520. stringBuilder.append("\" class=\"next\">");
  521. stringBuilder.append(getMessage().next);
  522. stringBuilder.append(" &#187;</a>");
  523. }
  524. stringBuilder.append("</p>");
  525. }
  526. /**
  527. * Adds the comments list to the StringBuffer content
  528. *
  529. * @param comments
  530. */
  531. private void writePostComments(List<Comment> comments) {
  532. stringBuilder.append("<div id=\"comments\">");
  533. stringBuilder.append("<h3>");
  534. stringBuilder.append(getMessage().comments);
  535. stringBuilder.append("</h3><dl>");
  536. Integer commentNumber = 1;
  537. for (Comment comment : comments) {
  538. stringBuilder.append("<dt id=\"" + comment.getKey().getId() + "\" class=\" odd first\">");
  539. stringBuilder.append("<a href=\"#" + comment.getKey().getId() + "\" class=\"comment-number\">" + commentNumber + ".</a>");
  540. if (comment.getDate() != null)
  541. stringBuilder.append(sdfWithHour.format(comment.getDate()));
  542. stringBuilder.append(" par ");
  543. String href = comment.getWebSite();
  544. if (href != null && !href.isEmpty()) {
  545. if (!href.startsWith("http://"))
  546. href = "http://" + href;
  547. stringBuilder.append("<a href=\"" + href + "\" rel=\"nofollow\">" + comment.getAlias() + "</a>");
  548. } else {
  549. stringBuilder.append(comment.getAlias());
  550. }
  551. stringBuilder.append("</dt><dd class=\" odd first\">");
  552. stringBuilder.append(replaceLinks(comment.getContent()));
  553. stringBuilder.append("</dd>");
  554. commentNumber++;
  555. }
  556. stringBuilder.append("</dl></div>");
  557. }
  558. /**
  559. * Write a Tag Cloud according to the tags in the model
  560. *
  561. * @param model
  562. */
  563. private void writeTagsCloud(StoryModel model) {
  564. List<HitsTag> tags = (List<HitsTag>) ((ArrayList<HitsTag>) model.getTags()).clone();
  565. assert tags != null;
  566. /*
  567. * if(tags.size() > 5) tags = tags.subList(0, 5);
  568. */
  569. long max = 100;
  570. if (tags != null && !tags.isEmpty() && tags.get(0).getHits() != null)
  571. max = tags.get(0).getHits();
  572. Collections.shuffle(tags, new Random());
  573. stringBuilder.append("<div id=\"content-info\">");
  574. stringBuilder.append("<h2>");
  575. stringBuilder.append(getMessage().tags);
  576. stringBuilder.append("</h2>");
  577. stringBuilder.append("</div>");
  578. stringBuilder.append("<div class=\"content-inner\"><ul class=\"tags\">");
  579. Long tagOccurency = 0l;
  580. for (HitsTag tag : tags) {
  581. if (tag.getHits() != null)
  582. tagOccurency = ((tag.getHits().intValue() * 100) / max);
  583. else
  584. tagOccurency = 0l;
  585. stringBuilder.append("<li><a href=\"");
  586. stringBuilder.append(getMessage().TAG_URL);
  587. stringBuilder.append("/");
  588. stringBuilder.append(tag.getName());
  589. stringBuilder.append("\" class=\"tag");
  590. stringBuilder.append(getTagRate(tagOccurency)).append("\"> ");
  591. stringBuilder.append(tag.getName());
  592. stringBuilder.append("</a> &nbsp;</li>");
  593. }
  594. stringBuilder.append("</ul>");
  595. stringBuilder.append("</div>");
  596. }
  597. }