PageRenderTime 31ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 1ms

/src/main/java/org/andya/confluence/plugins/metadata/AbstractMetadataMacro.java

https://bitbucket.org/jwalton/metadata-confluence-plugin
Java | 384 lines | 268 code | 47 blank | 69 comment | 39 complexity | b10ec4add687e85980520458526292fa MD5 | raw file
  1. /*
  2. * Copyright (c) 2006, 2007 Andy Armstrong, Kelsey Grant and other contributors.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. * * The names of contributors may not
  14. * be used to endorse or promote products derived from this software without
  15. * specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  21. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  24. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. package org.andya.confluence.plugins.metadata;
  29. import com.atlassian.confluence.core.ConfluenceEntityObject;
  30. import com.atlassian.confluence.core.ContentEntityObject;
  31. import com.atlassian.confluence.core.ContentPropertyManager;
  32. import com.atlassian.confluence.core.FormatSettingsManager;
  33. import com.atlassian.confluence.labels.LabelManager;
  34. import com.atlassian.confluence.pages.Page;
  35. import com.atlassian.confluence.pages.PageManager;
  36. import com.atlassian.confluence.renderer.PageContext;
  37. import com.atlassian.confluence.security.PermissionManager;
  38. import com.atlassian.confluence.spaces.SpaceManager;
  39. import com.atlassian.confluence.spaces.Space;
  40. import com.atlassian.confluence.user.AuthenticatedUserThreadLocal;
  41. import com.atlassian.renderer.RenderContext;
  42. import com.atlassian.renderer.RenderContextOutputType;
  43. import com.atlassian.renderer.v2.RenderMode;
  44. import com.atlassian.renderer.v2.SubRenderer;
  45. import com.atlassian.renderer.v2.macro.BaseMacro;
  46. import com.atlassian.renderer.v2.macro.MacroException;
  47. import com.atlassian.user.User;
  48. import com.atlassian.user.UserManager;
  49. import java.util.Map;
  50. import java.util.List;
  51. import java.util.Comparator;
  52. import java.util.Collections;
  53. import org.andya.confluence.utils.page.FindPage;
  54. import org.andya.confluence.utils.MacroUtils;
  55. import org.andya.confluence.utils.MacroConstants;
  56. import org.andya.confluence.utils.ContentService;
  57. import org.andya.confluence.plugins.metadata.model.MetadataContent;
  58. import org.andya.confluence.plugins.metadata.model.MetadataList;
  59. import org.andya.confluence.plugins.metadata.model.MetadataValue;
  60. import org.andya.confluence.plugins.metadata.model.MetadataSortOrder;
  61. import org.andya.confluence.plugins.metadata.renderers.MetadataRenderer;
  62. import org.andya.confluence.plugins.metadata.renderers.MetadataListRenderer;
  63. import org.andya.confluence.plugins.metadata.renderers.MetadataTableRenderer;
  64. /**
  65. * The base class of all metadata macros.
  66. */
  67. public abstract class AbstractMetadataMacro extends BaseMacro implements MacroConstants {
  68. private final String macroName;
  69. private SubRenderer subRenderer;
  70. private SpaceManager spaceManager;
  71. private PageManager pageManager;
  72. private UserManager userManager;
  73. private ContentService contentService;
  74. private ContentPropertyManager contentPropertyManager;
  75. private PermissionManager permissionManager;
  76. private LabelManager labelManager;
  77. private FormatSettingsManager formatSettingsManager;
  78. protected AbstractMetadataMacro(String macroName) {
  79. this.macroName = macroName;
  80. }
  81. public String getMacroName() {
  82. return macroName;
  83. }
  84. public SpaceManager getSpaceManager() {
  85. return spaceManager;
  86. }
  87. public void setSpaceManager(SpaceManager spaceManager) {
  88. this.spaceManager = spaceManager;
  89. }
  90. public PageManager getPageManager() {
  91. return pageManager;
  92. }
  93. public void setPageManager(PageManager pageManager) {
  94. this.pageManager = pageManager;
  95. }
  96. public UserManager getUserManager() {
  97. return userManager;
  98. }
  99. public void setUserManager(UserManager userManager) {
  100. this.userManager = userManager;
  101. }
  102. public FormatSettingsManager getFormatSettingsManager() {
  103. return formatSettingsManager;
  104. }
  105. public void setFormatSettingsManager(FormatSettingsManager formatSettingsManager) {
  106. this.formatSettingsManager = formatSettingsManager;
  107. }
  108. public PermissionManager getPermissionManager() {
  109. return permissionManager;
  110. }
  111. public void setPermissionManager(PermissionManager permissionManager) {
  112. this.permissionManager = permissionManager;
  113. }
  114. public ContentPropertyManager getContentPropertyManager() {
  115. return contentPropertyManager;
  116. }
  117. public void setContentPropertyManager(ContentPropertyManager contentPropertyManager) {
  118. this.contentPropertyManager = contentPropertyManager;
  119. }
  120. protected SubRenderer getSubRenderer() {
  121. return subRenderer;
  122. }
  123. public void setSubRenderer(SubRenderer subRenderer) {
  124. this.subRenderer = subRenderer;
  125. }
  126. public LabelManager getLabelManager() {
  127. return labelManager;
  128. }
  129. public void setLabelManager(LabelManager manager) {
  130. this.labelManager = manager;
  131. }
  132. /** Returns the current user. */
  133. public User getUser() {
  134. return AuthenticatedUserThreadLocal.getUser();
  135. }
  136. /** Returns the entity for the specified render context. */
  137. protected ContentEntityObject getEntity(RenderContext renderContext) {
  138. if (renderContext instanceof PageContext) {
  139. PageContext pageContext = (PageContext)renderContext;
  140. return pageContext.getEntity();
  141. }
  142. return null;
  143. }
  144. protected Page getPage(RenderContext renderContext) {
  145. ContentEntityObject ceo = getEntity(renderContext);
  146. if (ceo instanceof Page)
  147. return (Page)ceo;
  148. return null;
  149. }
  150. protected Page getPage(RenderContext renderContext, String pageName) throws MacroException {
  151. return getPage(renderContext, pageName, true);
  152. }
  153. protected Page getPage(RenderContext renderContext, String pageName, boolean required) throws MacroException {
  154. if (SELF_KEY.equalsIgnoreCase(pageName) || PARENT_KEY.equalsIgnoreCase(pageName)) {
  155. ContentEntityObject ceo = getEntity(renderContext);
  156. if (ceo instanceof Page) {
  157. Page page = (Page)ceo;
  158. if (PARENT_KEY.equalsIgnoreCase(pageName)) {
  159. page = page.getParent();
  160. if (page == null && required)
  161. throw new MacroException("No parent for page: " + page);
  162. }
  163. return page;
  164. }
  165. if (required)
  166. throw new MacroException("Cannot use " + pageName + " on a non-page: " + ceo);
  167. return null;
  168. }
  169. return new FindPage(getPageManager()).find(pageName, renderContext, null, required);
  170. }
  171. /**
  172. * Returns a named metadata value from the specified content object. The value is returned
  173. * as unrendered Wiki content so that it can be rendered appropriately on another page.
  174. * @param ceo The content object to return the metadata for.
  175. * @param valueName The name of the metadata value.
  176. * @return The unrendered Wiki content for the metadata value, or null if none is found.
  177. */
  178. public MetadataValue getMetadataValue(ContentEntityObject ceo, String valueName) {
  179. return getMetadataValue(ceo, valueName, null);
  180. }
  181. /**
  182. * Returns a named metadata value from the specified content object. The value is returned
  183. * as unrendered Wiki content so that it can be rendered appropriately on another page.
  184. * @param ceo The content object to return the metadata for.
  185. * @param valueName The name of the metadata value.
  186. * @param defaultValue The default value to return if none is set.
  187. * @return The unrendered Wiki content for the metadata value, or null if none is found.
  188. */
  189. public MetadataValue getMetadataValue(ContentEntityObject ceo, String valueName, String defaultValue) {
  190. return MetadataUtils.getMetadataValue(getContentService(), ceo, valueName, defaultValue);
  191. }
  192. public ContentService getContentService() {
  193. ContentService contentService = this.contentService;
  194. if (contentService == null) {
  195. contentService = new ContentService(getContentPropertyManager(), getSpaceManager(), getUserManager(),
  196. getFormatSettingsManager());
  197. this.contentService = contentService;
  198. }
  199. return contentService;
  200. }
  201. /**
  202. * Sets a named metadata value for the specified content object. The value specified should
  203. * be unrendered Wiki content so that the user of the value can choose how to render it.
  204. * @param ceo The content object to attach metadata to.
  205. * @param valueName The name of the metadata value.
  206. * @param unrenderedValue The unrendered Wiki content to be stored.
  207. */
  208. public void setMetadataValue(ContentEntityObject ceo, String valueName, String unrenderedValue) {
  209. MetadataUtils.setMetadataValue(getContentPropertyManager(), ceo, valueName, unrenderedValue);
  210. }
  211. /**
  212. * Sets a named metadata value for the content object associated with the current render context.
  213. * The value specified should be unrendered Wiki content so that the user of the value can choose
  214. * how to render it.
  215. * @param renderContext The render context in which this macro is executing.
  216. * @param valueName The name of the metadata value.
  217. * @param unrenderedValue The unrendered Wiki content to be stored.
  218. */
  219. public void setMetadataValue(RenderContext renderContext, String valueName, String unrenderedValue) {
  220. MetadataUtils.setMetadataValue(getContentPropertyManager(), renderContext, valueName, unrenderedValue);
  221. }
  222. /** Renders a page value for the given render context. */
  223. protected String renderValue(RenderContext renderContext, MetadataValue value) {
  224. String wikiSnippet = value != null ? value.getWikiSnippet() : "";
  225. return renderString(renderContext, wikiSnippet);
  226. }
  227. /** Renders a content entity object's metadata value. */
  228. protected String renderValue(RenderContext renderContext, ContentEntityObject ceo, MetadataValue value) {
  229. if (renderContext instanceof PageContext) {
  230. PageContext pageContext = new PageContext(ceo, (PageContext)renderContext);
  231. return renderValue(pageContext, value);
  232. } else {
  233. return renderValue(renderContext, value);
  234. }
  235. }
  236. /** Renders a string for the given render context. */
  237. protected String renderString(RenderContext renderContext, String string) {
  238. return getSubRenderer().render(string != null ? string : "", renderContext,
  239. renderContext.getRenderMode().and(RenderMode.suppress(RenderMode.F_FIRST_PARA)));
  240. }
  241. /** Renders a string for the specified content entity object. */
  242. protected String renderString(RenderContext renderContext, ContentEntityObject ceo, String string) {
  243. if (renderContext instanceof PageContext) {
  244. PageContext pageContext = new PageContext(ceo, (PageContext)renderContext);
  245. return renderString(pageContext, string);
  246. } else {
  247. return renderString(renderContext, string);
  248. }
  249. }
  250. /** Renders an exception to be displayed from a macro. */
  251. @SuppressWarnings("unchecked")
  252. protected String showRenderedExceptionString(Map parameters, Throwable e) {
  253. return MacroUtils.showRenderedExceptionString(parameters, "Unable to show \"" + getMacroName() + "\"", e);
  254. }
  255. /** Renders an exception to be displayed from a macro. */
  256. @SuppressWarnings("unchecked")
  257. protected String showRenderedExceptionString(Map parameters, String message) {
  258. return MacroUtils.showRenderedExceptionString(parameters, "Unable to show \"" + getMacroName() + "\"", message);
  259. }
  260. @SuppressWarnings("unchecked")
  261. protected String showUnrenderedExceptionString(Map parameters, Throwable e) {
  262. return MacroUtils.showUnrenderedExceptionString(parameters, "Unable to show \"" + getMacroName() + "\"", e);
  263. }
  264. @SuppressWarnings("unchecked")
  265. protected String showUnrenderedExceptionString(Map parameters, String message) {
  266. return MacroUtils.showUnrenderedExceptionString(parameters, "Unable to show \"" + getMacroName() + "\"", message);
  267. }
  268. protected String addMetadataList(Space space, String body, boolean hidden, boolean horizontal, String outputType)
  269. throws MacroException {
  270. return addMetadataList(space.getDescription(), body, hidden, horizontal, outputType);
  271. }
  272. protected String addMetadataList(ContentEntityObject ceo, String body, boolean hidden, boolean horizontal, String outputType)
  273. throws MacroException {
  274. MetadataList list = MetadataList.parseMetadataList(body);
  275. StringBuffer buffer = new StringBuffer();
  276. List<String> names = list.getNames();
  277. List<String> values = list.getValues();
  278. if(outputType == null || !outputType.equals(RenderContextOutputType.PREVIEW))
  279. {
  280. for (int i=0; i < names.size(); i++) {
  281. String valueName = (String)names.get(i);
  282. String value = (String)values.get(i);
  283. if(ceo != null)
  284. setMetadataValue(ceo, valueName, value);
  285. }
  286. }
  287. if (hidden)
  288. return "";
  289. if (horizontal) {
  290. for (int i=0; i < names.size(); i++) {
  291. String valueName = (String)names.get(i);
  292. buffer.append("||");
  293. buffer.append(valueName);
  294. }
  295. buffer.append("||\n");
  296. for (int i=0; i < names.size(); i++) {
  297. String value = (String)values.get(i);
  298. buffer.append("|");
  299. buffer.append(value.length() == 0 ? " " : value);
  300. }
  301. buffer.append("|\n");
  302. } else {
  303. for (int i=0; i < names.size(); i++) {
  304. String valueName = (String)names.get(i);
  305. String value = (String)values.get(i);
  306. buffer.append("||");
  307. buffer.append(valueName);
  308. buffer.append("|");
  309. buffer.append(value.length() == 0 ? " " : value);
  310. buffer.append("|\n");
  311. }
  312. }
  313. return buffer.toString();
  314. }
  315. /** Returns the preferred metadata renderer for the current macro. */
  316. @SuppressWarnings("unchecked")
  317. public MetadataRenderer getMetadataRenderer(Map parameters) throws MacroException {
  318. String style = MacroUtils.getStringParameter(parameters, STYLE_PARAMETER, DEFAULT_STYLE);
  319. if (LIST_STYLE_KEY.equals(style) || OL_STYLE_KEY.equals(style) || UL_STYLE_KEY.equals(style))
  320. return new MetadataListRenderer(getSubRenderer(), style);
  321. else if (TABLE_STYLE_KEY.equals(style))
  322. return new MetadataTableRenderer(getSubRenderer());
  323. else
  324. throw new MacroException("Unrecognized style " + style + " for metadata renderer");
  325. }
  326. @SuppressWarnings("unchecked")
  327. public List<MetadataContent> getSortedContents(Map parameters, List<ConfluenceEntityObject> entities, String defaultSortColumn) throws MacroException {
  328. List<MetadataContent> contents = MetadataUtils.getMetadataContent(getContentService(), entities);
  329. if (defaultSortColumn != null) {
  330. String commaDelimitedSort = MacroUtils.getStringParameter(parameters, SORT_PARAMETER, "");
  331. MetadataSortOrder[] sortOrders = MetadataSortOrder.getMetadataSortOrders(commaDelimitedSort);
  332. Comparator<MetadataContent> comparator = MetadataSortOrder.getComparator(sortOrders, defaultSortColumn);
  333. Collections.sort(contents, comparator);
  334. }
  335. return contents;
  336. }
  337. }