From 1148625bc645989b0a01b9f38c2a449aa2bca3ae Mon Sep 17 00:00:00 2001 From: Julian Hyde Date: Thu, 17 Jun 2010 03:39:04 +0000 Subject: [PATCH] Add Olap4jUtil.parseFormattedCellValue. git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@320 c6a108a4-781c-0410-a6c6-c2d559e19af0 --- src/org/olap4j/impl/Olap4jUtil.java | 87 +++++++++++++++++++++ testsrc/org/olap4j/impl/Olap4jUtilTest.java | 69 ++++++++++++++++ 2 files changed, 156 insertions(+) diff --git a/src/org/olap4j/impl/Olap4jUtil.java b/src/org/olap4j/impl/Olap4jUtil.java index f870271..314e7be 100644 --- a/src/org/olap4j/impl/Olap4jUtil.java +++ b/src/org/olap4j/impl/Olap4jUtil.java @@ -53,6 +53,12 @@ public class Olap4jUtil { private static final NamedList EMPTY_NAMED_LIST = new EmptyNamedList(); + private static final Pattern CELL_VALUE_REGEX1 = + Pattern.compile("\\s*([a-zA-Z][\\w\\.]*)\\s*=\\s*'([^']*)'"); + + private static final Pattern CELL_VALUE_REGEX2 = + Pattern.compile("\\s*([a-zA-Z][\\w\\.]*)\\s*=\\s*([^\\s]*)"); + static { String className; if (PreJdk15 || Retrowoven) { @@ -473,6 +479,87 @@ public static > Set enumSetAllOf( return compatible.enumSetAllOf(elementType); } + /** + * Parses a formatted cell values. + * + *

There is a customary way of including formatting infornation in cell + * values (started with Microsoft OLAP Services, and continued by JPivot and + * now Pentaho Analyzer). This method parses out the formatted value that + * should be displayed on the screen and also any properties present. + * + *

Examples:

    + *
  • "$123" no formatting information
  • + *
  • "|$123|style=red|" print in red style
  • + *
  • "|$123|style=red|arrow=up|" print in red style with an up arrow
  • + *
+ * + *

Properties

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
NameValueDescription
stylered|green|yellowrenders the Member in that color
linka urlcreates a hyperlink on the member
arrowup|down|blankpaints an arrow image
imagea uri. If the uri starts with "/" the context name will be + * prependedpaints image
+ * + * @param formattedValue Formatted cell value + * @param map Map into which to place (property, value) pairs + * @return Formatted cell value with properties removed + */ + public static String parseFormattedCellValue( + String formattedValue, + Map map) + { + if (formattedValue.startsWith("|")) { + String[] strs = formattedValue.substring(1).split("\\|"); + formattedValue = strs[0]; // original value + for (int i = 1; i < strs.length; i++) { + Matcher m = CELL_VALUE_REGEX1.matcher(strs[i]); + if (m.matches()) { + String propName = m.group(1); // property name + String propValue = m.group(2); // property value + map.put(propName, propValue); + continue; + } + + m = CELL_VALUE_REGEX2.matcher(strs[i]); + if (m.matches()) { + String propName = m.group(1); // property name + String propValue = m.group(2); // property value + map.put(propName, propValue); + continue; + } + + // it is not a key=value pair + // we add the String to the formatted value + formattedValue += strs[i]; + } + } + return formattedValue; + } + private enum DummyEnum { } diff --git a/testsrc/org/olap4j/impl/Olap4jUtilTest.java b/testsrc/org/olap4j/impl/Olap4jUtilTest.java index 54067c2..4079bf8 100644 --- a/testsrc/org/olap4j/impl/Olap4jUtilTest.java +++ b/testsrc/org/olap4j/impl/Olap4jUtilTest.java @@ -271,6 +271,75 @@ public void testUniqueNameToStringArray() { assertEquals("&", a.get(3)); assertEquals("2", a.get(4)); } + + public void testParseFormattedCellValue() { + // no formatting + checkParseFormattedCellValue("123", "123", "{}"); + + // no formatting, value contains '|' + checkParseFormattedCellValue("12|3", "12|3", "{}"); + + // empty string + checkParseFormattedCellValue("", "", "{}"); + + // one property + checkParseFormattedCellValue("|123|style=red|", "123", "{style=red}"); + + // multiple properties + checkParseFormattedCellValue( + "|123|style=red|arrow=up|", "123", "{arrow=up, style=red}"); + + // invalid property value -- we don't care + checkParseFormattedCellValue( + "|123|style=red|arrow=asdas|", "123", "{arrow=asdas, style=red}"); + + // empty value + checkParseFormattedCellValue("||style=red|", "", "{style=red}"); + + // empty property value + checkParseFormattedCellValue( + "|abc|style=|foo=bar|", "abc", "{foo=bar, style=}"); + + // REVIEW: spaces in property value cause it not to be recognized as a + // property + checkParseFormattedCellValue( + "|abc|style=xx|foo=bar baz|", "abcfoo=bar baz", "{style=xx}"); + + // spaces in property value recognized, provided property value is + // enclosed in quotes + checkParseFormattedCellValue( + "|abc|style=xx|foo='bar baz'|", "abc", "{foo=bar baz, style=xx}"); + + // '=' in property value + checkParseFormattedCellValue( + "|abc|style=xx|foo=baz=zz|", "abc", "{foo=baz=zz, style=xx}"); + + // missing '|' terminator + checkParseFormattedCellValue( + "|abc|foo=bar", "abc", "{foo=bar}"); + + // null value + try { + String s = + Olap4jUtil.parseFormattedCellValue( + null, new HashMap()); + fail("expected NPE, got " + s); + } catch (NullPointerException e) { + // ok + } + } + + private void checkParseFormattedCellValue( + String formattedCellValue, + String expectedCellValue, + String expectedProperties) + { + final TreeMap map = new TreeMap(); + final String cellValue = + Olap4jUtil.parseFormattedCellValue(formattedCellValue, map); + assertEquals("cell value", expectedCellValue, cellValue); + assertEquals("properties", expectedProperties, map.toString()); + } } // End Olap4jUtilTest.java