/src/main/java/org/andya/confluence/plugins/metadata/MetadataTableMacro.java
Java | 242 lines | 173 code | 20 blank | 49 comment | 43 complexity | c92627d139541837027c31e345301aa9 MD5 | raw file
- /*
- * Copyright (c) 2006, 2007 Andy Armstrong, Kelsey Grant and other contributors.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * The names of contributors may not
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- package org.andya.confluence.plugins.metadata;
-
- import com.atlassian.renderer.RenderContext;
- import com.atlassian.renderer.v2.RenderMode;
- import com.atlassian.renderer.v2.macro.MacroException;
-
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- import java.util.Map;
- import java.util.HashMap;
- import java.math.BigDecimal;
-
- import org.andya.confluence.utils.MacroUtils;
- import org.andya.confluence.plugins.metadata.model.MetadataContent;
- import org.andya.confluence.plugins.metadata.model.MetadataValue;
-
- /**
- * Macro allowing tablular data to be generated from metadata on matching pages.
- */
- public class MetadataTableMacro extends MetadataUsingMacro {
- private static final int SUMMARISE_SUM = 1;
- private static final int SUMMARIZE_COUNT = 2;
- private static final int SUMMARIZE_MAX = 3;
- private static final int SUMMARIZE_MIN = 4;
- private static final int SUMMARIZE_TEXT = 5;
-
- protected static final String X_KEY = "x";
- protected static final String Y_KEY = "y";
- protected static final String VALUE_KEY = "value";
- protected static final String SUM_KEY = "summarise";
- protected static final String VALUE_NAME_KEY = "value-name";
-
- public MetadataTableMacro() {
- super("metadata-table");
- }
-
- public RenderMode getBodyRenderMode() {
- return RenderMode.NO_RENDER;
- }
-
- /**
- * The metadata table macro.
- * Usage: {metadata-table:x=xvalue|y=yvalue|value=value|...}
- * Where: * xvalue - The value that will be used for the x axis of the table. This value
- * must exist in {metadata} tags in at least two other pages
- * * yvalue - The value that will be used for the y axis of the table. This value
- * must exist in {metadata} tags in at least two other pages
- * * value - The value that will be used to populate the body of the table. Ideally there
- * will be a value for each x-y cell on the table. Empty cells will have a value of " ".
- * * Other parameters are the same as for the {metadata-report} macro.
- */
- @SuppressWarnings("unchecked")
- public String execute(Map parameters, String body, RenderContext renderContext) throws MacroException {
- try {
- String xValue = MacroUtils.getStringParameter(parameters, X_KEY, null);
- String yValue = MacroUtils.getStringParameter(parameters, Y_KEY, null);
- String tableValue = MacroUtils.getStringParameter(parameters, VALUE_KEY, null);
- String summarise = MacroUtils.getStringParameter(parameters, SUM_KEY, "SUM");
-
- StringBuffer html = new StringBuffer();
- int maxResults = MacroUtils.getIntParameter(parameters, MAX_RESULTS_PARAMETER, DEFAULT_MAX_RESULTS);
- List<MetadataContent> contents = getMatchingPages(parameters, getContentService(), renderContext, true);
- int totalResults = contents.size();
- @SuppressWarnings("unused")
- boolean truncated = false;
- if (totalResults > maxResults) {
- contents = contents.subList(0, maxResults);
- truncated = true;
- }
- //Set up the summarise constant for a little optimisation to save
- //a few string comparisons.
- int sum = SUMMARISE_SUM;
- if (summarise.compareToIgnoreCase("SUM") == 0) {
- sum = SUMMARISE_SUM;
- } else if (summarise.compareToIgnoreCase("COUNT") == 0) {
- sum = SUMMARIZE_COUNT;
- } else if (summarise.compareToIgnoreCase("MAX") == 0) {
- sum = SUMMARIZE_MAX;
- } else if (summarise.compareToIgnoreCase("MIN") == 0) {
- sum = SUMMARIZE_MIN;
- } else if (summarise.compareToIgnoreCase("TEXT") == 0) {
- sum = SUMMARIZE_TEXT;
- }
-
- List<MetadataValue> yValues = new ArrayList<MetadataValue>();
- List<MetadataValue> xValues = new ArrayList<MetadataValue>();
- HashMap<MetadataValue, HashMap<MetadataValue, Object>> table = new HashMap<MetadataValue, HashMap<MetadataValue, Object>>();
- HashMap<MetadataValue, Object> col;
- BigDecimal currentNumber;
- BigDecimal lastNumber = new BigDecimal(0);
- //Lookup all the x values
- for (MetadataContent content : contents) {
- MetadataValue y = content.getMetadataValue(yValue);
- MetadataValue x = content.getMetadataValue(xValue);
- MetadataValue currentValue = content.getMetadataValue(tableValue);
- Number tempNumber = currentValue != null ? currentValue.getValueAsNumber() : null;
- if (tempNumber == null) {
- currentNumber = new BigDecimal(0);
- } else {
- currentNumber = new BigDecimal(tempNumber.doubleValue());
- }
-
- if (!yValues.contains(y.getWikiSnippet())) {
- yValues.add(y);
- col = new HashMap<MetadataValue, Object>();
- table.put(y, col);
- } else {
- col = table.get(y);
- }
-
- if (!xValues.contains(x.getWikiSnippet())) {
- xValues.add(x);
- }
-
- //Setup some initial values
- if (sum != SUMMARIZE_TEXT) {
- if (col.get(x) != null) {
- lastNumber = (BigDecimal)col.get(x);
- } else {
- if (sum == SUMMARIZE_MIN) {
- lastNumber = new BigDecimal(Integer.MAX_VALUE);
- } else if (sum == SUMMARIZE_MIN) {
- lastNumber = new BigDecimal(Integer.MAX_VALUE);
- } else {
- lastNumber = new BigDecimal(0);
- }
- }
- }
-
- switch (sum) {
- case SUMMARIZE_TEXT: {
- col.put(x, MetadataValue.getWikiSnippet(currentValue));
- break;
- }
- case SUMMARIZE_COUNT: {
- col.put(x, new BigDecimal(lastNumber.intValue() + 1));
- break;
- }
- case SUMMARIZE_MIN: {
- if (lastNumber.compareTo(currentNumber) >= 0) {
- col.put(x, currentNumber);
- }
- break;
- }
- case SUMMARIZE_MAX: {
- if (lastNumber.compareTo(currentNumber) < 0) {
- col.put(x, currentNumber);
- }
- break;
- }
- default: { //Default is SUMMARISE_SUM
- col.put(x, new BigDecimal(currentNumber.intValue() + lastNumber.intValue()));
- }
- }
- }
-
- //Sort the y axis
- try {
- Collections.sort(yValues);
- }
- catch (Exception e) {
- //Can't sort the table's y axis.
- }
-
- //Sort the x axis
- try {
- Collections.sort(xValues);
- }
- catch (Exception e) {
- //Can't sort the table's x axis.
- }
-
- html.append("<table class='confluencetable'>\n");
- html.append("<tr>");
- html.append("<th class='confluenceTh'>");
- html.append(xValue);
- html.append("</th>");
- for (int i = 0; i < yValues.size(); i++) {
- html.append("<th class='confluenceTh'>");
- html.append(yValues.get(i));
- html.append("</th>");
- }
- html.append("</tr>");
-
- for (int i = 0; i < xValues.size(); i++) {
- html.append("<tr>\n");
- html.append("<th class='confluenceTh'>");
- html.append(xValues.get(i));
- html.append("</th>");
- for (int j = 0; j < yValues.size(); j++) {
- html.append("<td class='confluenceTd'>");
- try {
- col = table.get(yValues.get(j));
- if (col != null) {
- html.append(col.get(xValues.get(i)));
- } else {
- html.append(" ");
- }
- } catch (Exception e) {
- html.append(" ");
- }
- html.append("</td>\n");
- }
- html.append("</tr>\n");
- }
- html.append("</table>\n");
- return html.toString();
-
- } catch (Exception e) {
- return MacroUtils.showRenderedExceptionString(parameters, "Unable to render metadata table macro", e);
- }
- }
- }