TemplateUtil.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
org.pentaho.core.util |
![]() |
![]() |
Pentaho |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* Copyright 2006 Pentaho Corporation. All rights reserved.
* This software was developed by Pentaho Corporation and is provided under the terms
* of the Mozilla Public License, Version 1.1, or any later version. You may not use
* this file except in compliance with the license. If you need a copy of the license,
* please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
* BI Platform. The Initial Developer is Pentaho Corporation.
*
* Software distributed under the Mozilla Public License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
* the license for the specific language governing your rights and limitations.
*
* @created Mar 16, 2006
* @author James Dixon
*/
package org.pentaho.core.util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.commons.connection.IPentahoMetaData;
import org.pentaho.commons.connection.IPentahoResultSet;
import org.pentaho.core.runtime.IRuntimeContext;
import org.pentaho.core.solution.IParameterProvider;
import org.pentaho.core.system.PentahoSystem;
import org.pentaho.messages.Messages;
import org.pentaho.util.DateMath;
public class TemplateUtil {
private final static String PARAMETER_PATTERN = "\\{([^\\}\\{\\s]*)\\}"; //$NON-NLS-1$
private final static String DATE_EXPR_PATTERN = "([\\+\\-]?(\\d*):(\\p{Alpha}{1,2}))([ \t]+[\\+\\-]?(\\d*):(\\p{Alpha}{1,2}))*([ \t]*;(.*))?"; //$NON-NLS-1$
private static final Pattern parameterExpressionPattern = Pattern.compile(PARAMETER_PATTERN);
private static final Pattern dateExpressionPattern = Pattern.compile(DATE_EXPR_PATTERN);
private static final List SystemInputs = new ArrayList();
private static final Log logger = LogFactory.getLog(TemplateUtil.class);
static {
SystemInputs.add("$user");//$NON-NLS-1$
SystemInputs.add("$url");//$NON-NLS-1$
SystemInputs.add("$solution"); //$NON-NLS-1$
}
public static String getSystemInput(String inputName, IRuntimeContext context) {
int i = SystemInputs.indexOf(inputName);
switch (i) {
case 0: { // User
return context.getSession().getName();
}
case 1: { // BaseURL
return PentahoSystem.getApplicationContext().getBaseUrl();
}
case 2: { // Solution
return PentahoSystem.getApplicationContext().getSolutionPath(""); //$NON-NLS-1$
}
}
return null;
}
public static String applyTemplate(String template, IRuntimeContext context, IParameterResolver resolver) {
return applyTemplate(template, new InputProperties(context), resolver);
}
public static String applyTemplate(String template, IRuntimeContext context) {
return applyTemplate(template, new InputProperties(context), null);
}
public static String applyTemplate(String template, IRuntimeContext context, String parameterPatternStr) {
Pattern pattern = Pattern.compile(parameterPatternStr);
return applyTemplate(template, new InputProperties(context), pattern, null);
}
public static String applyTemplate(String template, Properties inputs, IParameterResolver resolver) {
return applyTemplate(template, inputs, parameterExpressionPattern, resolver);
}
/**
* Processes a template by processing the parameters declared in the
* template. The parameters to be replaced are enclosed in curly brackets.
* Parameters can be the input values (as specified by the name of the input
* value) or date expressions. Parameters that can not be processed are left
* in the template.
*
* @param template
* the template specification.
* @param input
* the input values communicated as a
* {@link java.util.Properties}.
* @param locale
* the locale to use for the formatting of date expression. If
* <tt>null</tt>, the locale for the thread is used. If no
* locale for the thread, then the default locale is used.
* @throws IllegalArgumentException
* if a date expression is illegal
* @see DateMath#calculateDateString(Calendar, String)
* @see PentahoSystem#getLocale()
* @see PentahoSystem#getDefaultLocale()
*/
public static String applyTemplate(String template, Properties inputs, Pattern parameterPattern,
IParameterResolver resolver) {
StringBuffer results = new StringBuffer();
Matcher parameterMatcher = parameterPattern.matcher(template);
int copyStart = 0;
while (parameterMatcher.find()) {
int start = parameterMatcher.start();
String parameter = parameterMatcher.group(1);
String value = null;
int pos1 = parameter.indexOf(":col:");//$NON-NLS-1$
if (pos1 > -1) {
applyTableTemplate(template, inputs, parameterPattern, results);
return results.toString();
}
pos1 = parameter.indexOf(':');
if (pos1 > -1) {
// Allow alternate parameter resolution to be provided by the
// component.
if (resolver != null) {
int newCopyStart = resolver.resolveParameter(template, parameter, parameterMatcher, copyStart, results);
if (newCopyStart >= 0) {
copyStart = newCopyStart;
continue;
}
}
StringTokenizer tokenizer = new StringTokenizer(parameter, ":"); //$NON-NLS-1$
if (tokenizer.countTokens() >= 5) {
// this looks like a data table key
parameter = tokenizer.nextToken();
String keyColumn = tokenizer.nextToken();
String keyValue = tokenizer.nextToken();
String valueColumn = tokenizer.nextToken();
StringBuffer defaultValue = new StringBuffer();
defaultValue.append(tokenizer.nextToken());
while (tokenizer.hasMoreTokens()) {
defaultValue.append(':').append(tokenizer.nextToken());
}
// see if we can find this in the data
if (inputs instanceof InputProperties) {
value = ((InputProperties) inputs).getProperty(parameter, keyColumn, keyValue, valueColumn, defaultValue
.toString());
}
}
}
if (value == null) {
// TODO support type conversion
value = inputs.getProperty(parameter);
}
results.append(template.substring(copyStart, start));
copyStart = parameterMatcher.end();
if (value == null) {
Matcher dateMatcher = dateExpressionPattern.matcher(parameter);
if (dateMatcher.matches()) {
value = DateMath.calculateDateString(null, parameter);
}
}
if (value == null) {
results.append(parameterMatcher.group());
} else {
results.append(value);
}
}
if (copyStart < template.length()) {
results.append(template.substring(copyStart));
}
return results.toString();
}
public static void applyTableTemplate(String template, Properties inputs, Pattern parameterPattern,
StringBuffer results) {
Matcher parameterMatcher = parameterPattern.matcher(template);
ArrayList partsList = new ArrayList();
ArrayList columnsList = new ArrayList();
int idx = 0;
int lastEnd = 0;
IPentahoResultSet data = null;
while (parameterMatcher.find()) {
int start = parameterMatcher.start();
String parameter = parameterMatcher.group(1);
// pull out the repeating part
int pos1 = parameter.indexOf(":col:");//$NON-NLS-1$
if (pos1 > -1) {
String part = template.substring(lastEnd, start);
logger.debug("parameter=" + parameter);//$NON-NLS-1$
logger.debug("part=" + part);//$NON-NLS-1$
String inputName = parameter.substring(0, pos1);
String columnNoStr = parameter.substring(pos1 + 5);
int columnNo = Integer.parseInt(columnNoStr);
logger.debug("inputName=" + inputName);//$NON-NLS-1$
logger.debug("columnNoStr=" + columnNoStr);//$NON-NLS-1$
logger.debug("columnNo=" + columnNo);//$NON-NLS-1$
Object obj = null;
if (inputs instanceof InputProperties) {
obj = ((InputProperties) inputs).getInput(inputName);
}
if (obj == null) {
logger.debug(Messages.getString("TemplateUtil.NOT_FOUND", inputName)); //$NON-NLS-1$
} else {
if (obj instanceof IPentahoResultSet) {
data = (IPentahoResultSet) obj;
if (columnNo < data.getColumnCount()) {
columnsList.add(new Integer(columnNo));
} else {
logger.debug(Messages.getString("TemplateUtil.INVALID_COLUMN", String.valueOf(columnNo))); //$NON-NLS-1$
}
}
}
partsList.add(part);
lastEnd = parameterMatcher.end();
} else {
// don't support this yet
}
}
logger.debug("partsList.size()=" + partsList.size());//$NON-NLS-1$
logger.debug("columnsList.size()=" + columnsList.size());//$NON-NLS-1$
logger.debug("data=" + data);//$NON-NLS-1$
if (partsList.size() > 0) {
partsList.add(template.substring(lastEnd));
} else {
logger.debug(Messages.getString("TemplateUtil.NO_TOKEN")); //$NON-NLS-1$
}
if (data != null && (partsList.size() == columnsList.size() + 1)) {
// here we go
String parts[] = new String[partsList.size()];
partsList.toArray(parts);
Integer cols[] = new Integer[columnsList.size()];
columnsList.toArray(cols);
int rowNo = 0;
Object row[] = data.getDataRow(rowNo);
while (row != null) {
for (idx = 0; idx < cols.length; idx++) {
results.append(parts[idx]);
results.append(row[cols[idx].intValue()]);
}
results.append(parts[parts.length - 1]);
rowNo++;
row = data.getDataRow(rowNo);
}
}
logger.debug("results=" + results.toString());//$NON-NLS-1$
}
public static String applyTemplate(String template, String name, String value) {
String result = template;
result = result.replaceAll("\\{" + name + "\\}", value); //$NON-NLS-1$//$NON-NLS-2$
return result;
}
public static String applyTemplate(String template, String name, String[] value) {
if (value == null) {
return (template);
}
if (value.length == 1) {
return (applyTemplate(template, name, value[0]));
}
int pos = template.indexOf("{" + name + "}"); //$NON-NLS-1$ //$NON-NLS-2$
if (pos == -1) {
return (template);
}
int startPos = template.substring(0, pos).lastIndexOf('&');
if (startPos < 0) {
startPos = template.substring(0, pos).lastIndexOf('?');
}
if (startPos < 0) {
startPos = 0;
} else {
startPos += 1;
}
int endPos = template.substring(pos + name.length() + 1).indexOf('&');
if (endPos < 0) {
endPos = template.substring(pos + name.length() + 1).indexOf('#');
}
if (endPos < 0) {
endPos = template.length();
} else {
endPos += pos + name.length() + 1;
}
String result = template.substring(0, startPos);
String replacePart = template.substring(startPos, endPos);
result += replacePart.replaceAll("\\{" + name + "\\}", value[0]); //$NON-NLS-1$ //$NON-NLS-2$
for (int i = 1; i < value.length; ++i) {
result += "&" + replacePart.replaceAll("\\{" + name + "\\}", value[i]); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
}
result += template.substring(endPos);
return result;
}
/**
* Acts as a facade for a {@link IRuntimeContext} to access the input values
* as from a {@link java.util.Properties Properties}. The class only
* overrides the {@link #getProperty(String)} method, as its is the only
* method used in
* {@link TemplateComponent#applyTemplate(String, IRuntimeContext) TemplateComponent.applyTemplate(String, IRuntimeContext)}.
*/
private static class InputProperties extends Properties {
private static final long serialVersionUID = 1L;
Pattern dateExpressionRegexPattern = Pattern.compile(DATE_EXPR_PATTERN);
private IRuntimeContext context;
private Set inputs;
private static final Log logger = LogFactory.getLog(InputProperties.class);
InputProperties(IRuntimeContext context) {
this.context = context;
inputs = new HashSet();
inputs.addAll(context.getInputNames());
inputs.add("$user"); //$NON-NLS-1$
inputs.add("$url"); //$NON-NLS-1$
inputs.add("$solution"); //$NON-NLS-1$
}
public int size() {
if (inputs == null) {
return 0;
} else {
return inputs.size();
}
}
public String getProperty(String parameter, String keyColumn, String keyValue, String valueColumn,
String defaultValue) {
if (!context.getInputNames().contains(parameter)) {
// leave the text alone
return "{" + parameter + ":" + keyColumn + ":" + keyValue + ":" + valueColumn + ":" + defaultValue + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
}
Object valueObj = context.getInputParameterValue(parameter);
if (valueObj instanceof IPentahoResultSet) {
IPentahoResultSet data = (IPentahoResultSet) valueObj;
// this is slow
// TODO implement mapping or sorting here to improve performance
int keyColumnNo = data.getMetaData().getColumnIndex(keyColumn);
if (keyValue.indexOf('_') > 0) {
keyValue = keyValue.replace('_', ' ');
}
int valueColumnNo = data.getMetaData().getColumnIndex(valueColumn);
if (keyColumnNo != -1 && valueColumnNo != -1) {
for (int row = 0; row < data.getRowCount(); row++) {
Object thisKey = data.getValueAt(row, keyColumnNo);
if (thisKey != null) {
if (keyValue.equals(thisKey.toString())) {
// we found the value
// TODO support typing here
return data.getValueAt(row, valueColumnNo).toString();
}
}
}
}
}
return defaultValue;
}
public Object getInput(String name) {
Object value = null;
if (inputs == null) {
return null;
}
if (inputs.contains(name)) {
value = TemplateUtil.getSystemInput(name, context);
if (value != null) {
return value;
}
value = context.getInputParameterValue(name);
}
return value;
}
public String getProperty(String name) {
String value = null;
if (inputs == null) {
return null;
}
if (inputs.contains(name)) {
value = TemplateUtil.getSystemInput(name, context);
if (value != null) {
return value;
}
Object valueObj = context.getInputParameterValue(name);
if (valueObj instanceof String) {
value = (String) valueObj;
} else if (valueObj instanceof Object[]) {
Object values[] = (Object[]) valueObj;
StringBuffer valuesBuffer = new StringBuffer();
// TODO support non-string items
// TODO this is assuming that the surrounding 's exist
for (int i = 0; i < values.length; i++) {
if (i == 0) {
valuesBuffer.append("'").append(values[i].toString()).append("'"); //$NON-NLS-1$ //$NON-NLS-2$
} else {
valuesBuffer.append(",'").append(values[i].toString()).append("'"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
String valueStr = valuesBuffer.toString();
value = valueStr.substring(1, valueStr.length() - 1);
} else if (valueObj instanceof IPentahoResultSet) {
IPentahoResultSet rs = (IPentahoResultSet) valueObj;
// See if we can find a column in the metadata with the same
// name as the input
IPentahoMetaData md = rs.getMetaData();
int columnIdx = -1;
if (md.getColumnCount() == 1) {
columnIdx = 0;
} else {
columnIdx = md.getColumnIndex(new String[] { name });
}
if (columnIdx < 0) {
logger.error(Messages.getErrorString("Template.ERROR_0005_COULD_NOT_DETERMINE_COLUMN")); //$NON-NLS-1$
return null;
}
int rowCount = rs.getRowCount();
Object valueCell = null;
StringBuffer valuesBuffer = new StringBuffer();
// TODO support non-string columns
for (int i = 0; i < rowCount; i++) {
valueCell = rs.getValueAt(i, columnIdx);
if (i == 0) {
valuesBuffer.append("'").append(valueCell.toString()).append("'"); //$NON-NLS-1$ //$NON-NLS-2$
} else {
valuesBuffer.append(",'").append(valueCell.toString()).append("'"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
String valueStr = valuesBuffer.toString();
// TODO Assumes that parameter is already surrounded by
// quotes.
value = valueStr.substring(1, valueStr.length() - 1);
} else if (valueObj != null) {
value = valueObj.toString();
}
// TODO add support for numeric classes
} else {
value = super.getProperty(name);
}
if (value == null) {
Matcher dateMatcher = dateExpressionRegexPattern.matcher(name);
if (dateMatcher.matches()) {
value = DateMath.calculateDateString(null, name);
}
} else {
Matcher dateMatcher = dateExpressionRegexPattern.matcher(value);
if (dateMatcher.matches()) {
value = DateMath.calculateDateString(null, value);
}
}
return value;
}
}
public static Properties parametersToProperties(IParameterProvider parameterProvider) {
Properties properties = new Properties();
Iterator names = parameterProvider.getParameterNames();
while (names.hasNext()) {
String name = (String) names.next();
String value = parameterProvider.getStringParameter(name, null);
if (value != null) {
properties.put(name, value);
}
}
return properties;
}
}
The table below shows all metrics for TemplateUtil.java.




