PageRenderTime 32ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/swizzle-blogrss-macro/src/main/java/org/codehaus/swizzle/blogrss/BlogRssMacro.java

https://gitlab.com/mfriedenhagen/swizzle
Java | 214 lines | 161 code | 37 blank | 16 comment | 37 complexity | ce6dfdb052b04e751485671a4cbc02f0 MD5 | raw file
  1. /**
  2. *
  3. * Copyright 2006 David Blevins
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package org.codehaus.swizzle.blogrss;
  18. import com.atlassian.confluence.renderer.radeox.macros.MacroUtils;
  19. import com.atlassian.confluence.renderer.v2.macros.BaseHttpRetrievalMacro;
  20. import com.atlassian.confluence.util.http.HttpResponse;
  21. import com.atlassian.confluence.util.io.IOUtils;
  22. import com.atlassian.confluence.util.velocity.VelocityUtils;
  23. import com.atlassian.renderer.RenderContext;
  24. import com.atlassian.renderer.v2.RenderUtils;
  25. import com.atlassian.renderer.v2.macro.MacroException;
  26. import com.sun.syndication.feed.synd.SyndContent;
  27. import com.sun.syndication.feed.synd.SyndEntry;
  28. import com.sun.syndication.feed.synd.SyndFeed;
  29. import com.sun.syndication.feed.synd.SyndLink;
  30. import com.sun.syndication.io.FeedException;
  31. import com.sun.syndication.io.SyndFeedInput;
  32. import com.sun.syndication.io.XmlReader;
  33. import org.apache.log4j.Logger;
  34. import java.io.ByteArrayInputStream;
  35. import java.io.ByteArrayOutputStream;
  36. import java.io.IOException;
  37. import java.io.InputStream;
  38. import java.text.SimpleDateFormat;
  39. import java.util.Iterator;
  40. import java.util.List;
  41. import java.util.Map;
  42. public class BlogRssMacro extends BaseHttpRetrievalMacro {
  43. private Logger log = Logger.getLogger(this.getClass());
  44. private byte[] readResponse(HttpResponse response) throws IOException {
  45. InputStream in;
  46. ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
  47. in = response.getResponse();
  48. int read;
  49. byte[] bytes = new byte[1024];
  50. while ((read = in.read(bytes)) != -1) {
  51. bytesOut.write(bytes, 0, read);
  52. }
  53. return bytesOut.toByteArray();
  54. }
  55. public String successfulResponse(Map parameters, RenderContext renderContext, String url, HttpResponse response) throws MacroException {
  56. Integer maxItems = new Integer(param(parameters, "max", 1, "5"));
  57. String s = param(parameters, "truncate", 3, "450");
  58. int truncate;
  59. if ("false".equalsIgnoreCase(s)){
  60. truncate = 0;
  61. } else {
  62. truncate = new Integer(s);
  63. }
  64. SyndFeed feed;
  65. byte[] webContent = null;
  66. try {
  67. webContent = readResponse(response);
  68. feed = parseRSSFeed(url, webContent);
  69. }
  70. catch (Exception e) {
  71. if (webContent != null && response.getContentType().indexOf("html") != -1) {
  72. throw new MacroException("The RSS macro is retrieving an HTML page.");
  73. }
  74. throw new MacroException("Error parsing RSS feed: " + e.toString());
  75. }
  76. String blogUrl = null;
  77. List links = feed.getLinks();
  78. if (links != null) for (Iterator iterator = links.iterator(); iterator.hasNext();) {
  79. Object o = iterator.next();
  80. if (o instanceof SyndLink) {
  81. SyndLink link = (SyndLink) o;
  82. if ("alternate".equals(link.getRel())) {
  83. blogUrl = link.getHref();
  84. }
  85. }
  86. }
  87. if (blogUrl == null && feed.getLink().endsWith("/feed/entries/atom")){
  88. blogUrl = feed.getLink().replaceAll("/feed/entries/atom$","");
  89. }
  90. List entries = feed.getEntries();
  91. for (Iterator iterator = entries.iterator(); iterator.hasNext();) {
  92. SyndEntry entry = (SyndEntry) iterator.next();
  93. log.error("blogrss: entry " + entry.getTitle() + " " + entry);
  94. SyndContent description = entry.getDescription();
  95. if (description == null) {
  96. List contents = entry.getContents();
  97. if (contents == null) {
  98. log.error("blogrss: contents are null");
  99. continue;
  100. }
  101. for (Object o : contents) {
  102. if (o instanceof SyndContent) {
  103. SyndContent content = (SyndContent) o;
  104. truncate(truncate, content, entry.getLink());
  105. entry.setDescription(content);
  106. break;
  107. }
  108. }
  109. } else {
  110. truncate(truncate, description, entry.getLink());
  111. entry.setDescription(description);
  112. }
  113. }
  114. Map contextMap = MacroUtils.defaultVelocityContext();
  115. contextMap.put("url", url);
  116. contextMap.put("blogUrl", blogUrl);
  117. contextMap.put("urlHash", new Integer(url.hashCode()));
  118. contextMap.put("feed", feed);
  119. contextMap.put("max", maxItems);
  120. contextMap.put("linkDate", new SimpleDateFormat("yyyyMMdd")); // 20091105
  121. contextMap.put("shortDate", new SimpleDateFormat("dd MMM @ h:mm a")); // 05 Nov @ 10:46 AM
  122. contextMap.put("longDate", new SimpleDateFormat("EEEE, MMMM d, yyyy")); // Wednesday, November 5, 2008
  123. try {
  124. return VelocityUtils.getRenderedTemplate("swizzle/blogrss/templates/blogrss.vm", contextMap);
  125. } catch (Exception e) {
  126. log.error("Error while trying to assemble the RSS result!", e);
  127. throw new MacroException(e.getMessage());
  128. }
  129. }
  130. private void truncate(int truncate, SyndContent description, String url) {
  131. if (truncate > 0) {
  132. String s = description.getValue();
  133. String content = abbreviate(truncate, s, url);
  134. if (content.endsWith("...")) content += " <a href=\""+ url +"\"><i>(more)</i></a>";
  135. description.setValue(content);
  136. }
  137. }
  138. private String abbreviate(int truncate, String s, String url) {
  139. int count = 0;
  140. if (s.length() <= truncate) return s;
  141. StringBuilder sb = new StringBuilder(truncate*2);
  142. boolean skipping = false;
  143. for (int i = 0; i < s.length(); i++) {
  144. char c = s.charAt(i);
  145. sb.append(c);
  146. if ('<' == c){
  147. skipping = true;
  148. }
  149. if (skipping && '>' == c) {
  150. skipping = false;
  151. }
  152. if (!skipping) count++;
  153. if (count> truncate) {
  154. sb.append("... <a href=\"").append(url).append("\"><i>(more)</i></a>");
  155. break;
  156. }
  157. }
  158. return sb.toString();
  159. }
  160. private String param(Map parameters, String name, int i, String defaultValue) {
  161. String m = RenderUtils.getParameter(parameters, name, i);
  162. return (m != null && !"".equals(m)) ? m : defaultValue;
  163. }
  164. private SyndFeed parseRSSFeed(String url, byte[] webContent) throws IOException {
  165. ByteArrayInputStream bufferedIn = null;
  166. try {
  167. bufferedIn = new ByteArrayInputStream(webContent);
  168. SyndFeedInput input = new SyndFeedInput();
  169. return input.build(new XmlReader(bufferedIn));
  170. } catch (FeedException e) {
  171. log.error("Error while trying to assemble the RSS result!", e);
  172. throw new IOException(e.getMessage());
  173. } finally {
  174. IOUtils.close(bufferedIn);
  175. }
  176. }
  177. }