Skip to content

Commit

Permalink
Add Olap4jUtil.parseFormattedCellValue.
Browse files Browse the repository at this point in the history
git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@320 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
julianhyde committed Jun 17, 2010
1 parent 141d730 commit 1148625
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 0 deletions.
87 changes: 87 additions & 0 deletions src/org/olap4j/impl/Olap4jUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -473,6 +479,87 @@ public static <E extends Enum<E>> Set<E> enumSetAllOf(
return compatible.enumSetAllOf(elementType);
}

/**
* Parses a formatted cell values.
*
* <p>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.
*
* <p>Examples:<ul>
* <li>"$123" no formatting information</li>
* <li>"|$123|style=red|" print in red style</li>
* <li>"|$123|style=red|arrow=up|" print in red style with an up arrow</li>
* </ul>
*
* <h4>Properties</h4>
*
* <table border="1">
* <tr>
* <th>Name</th>
* <th>Value</th>
* <th>Description</th>
* </tr>
* <tr>
* <td>style</td>
* <td>red|green|yellow</td>
* <td>renders the Member in that color</td>
* </tr>
* <tr>
* <td>link</td>
* <td>a url</td>
* <td>creates a hyperlink on the member</td>
* </tr>
* <tr>
* <td>arrow</td>
* <td>up|down|blank</td>
* <td>paints an arrow image</td>
* </tr>
* <tr>
* <td>image</td>
* <td>a uri. If the uri starts with "/" the context name will be
* prepended</td>
* <td>paints image</td>
* </tr>
* </table>
*
* @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<String, String> 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 {
}

Expand Down
69 changes: 69 additions & 0 deletions testsrc/org/olap4j/impl/Olap4jUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, String>());
fail("expected NPE, got " + s);
} catch (NullPointerException e) {
// ok
}
}

private void checkParseFormattedCellValue(
String formattedCellValue,
String expectedCellValue,
String expectedProperties)
{
final TreeMap<String, String> map = new TreeMap<String, String>();
final String cellValue =
Olap4jUtil.parseFormattedCellValue(formattedCellValue, map);
assertEquals("cell value", expectedCellValue, cellValue);
assertEquals("properties", expectedProperties, map.toString());
}
}

// End Olap4jUtilTest.java

0 comments on commit 1148625

Please sign in to comment.