KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pentaho > core > util > TemplateUtil


1 /*
2  * Copyright 2006 Pentaho Corporation. All rights reserved.
3  * This software was developed by Pentaho Corporation and is provided under the terms
4  * of the Mozilla Public License, Version 1.1, or any later version. You may not use
5  * this file except in compliance with the license. If you need a copy of the license,
6  * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
7  * BI Platform. The Initial Developer is Pentaho Corporation.
8  *
9  * Software distributed under the Mozilla Public License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
11  * the license for the specific language governing your rights and limitations.
12  *
13  * @created Mar 16, 2006
14  * @author James Dixon
15  */

16
17 package org.pentaho.core.util;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.HashSet JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Properties JavaDoc;
24 import java.util.Set JavaDoc;
25 import java.util.StringTokenizer JavaDoc;
26 import java.util.regex.Matcher JavaDoc;
27 import java.util.regex.Pattern JavaDoc;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.pentaho.core.connection.IPentahoMetaData;
32 import org.pentaho.core.connection.IPentahoResultSet;
33 import org.pentaho.core.runtime.IRuntimeContext;
34 import org.pentaho.core.solution.IParameterProvider;
35 import org.pentaho.core.system.PentahoSystem;
36 import org.pentaho.messages.Messages;
37 import org.pentaho.util.DateMath;
38
39 public class TemplateUtil {
40
41     private final static String JavaDoc PARAMETER_PATTERN = "\\{([^\\}\\{\\s]*)\\}"; //$NON-NLS-1$
42
private final static String JavaDoc DATE_EXPR_PATTERN = "([\\+\\-]?(\\d*):(\\p{Alpha}{1,2}))([ \t]+[\\+\\-]?(\\d*):(\\p{Alpha}{1,2}))*([ \t]*;(.*))?"; //$NON-NLS-1$
43
private static final Pattern JavaDoc parameterExpressionPattern = Pattern.compile(PARAMETER_PATTERN);
44     private static final Pattern JavaDoc dateExpressionPattern = Pattern.compile(DATE_EXPR_PATTERN);
45     private static final List JavaDoc SystemInputs = new ArrayList JavaDoc();
46     
47     static {
48       SystemInputs.add("$user");//$NON-NLS-1$
49
SystemInputs.add("$url");//$NON-NLS-1$
50
SystemInputs.add("$solution"); //$NON-NLS-1$
51
}
52      
53     public static String JavaDoc getSystemInput(String JavaDoc inputName, IRuntimeContext context) {
54       int i = SystemInputs.indexOf(inputName);
55       switch (i) {
56         case 0: { // User
57
return context.getSession().getName();
58         }
59         case 1: { // BaseURL
60
return PentahoSystem.getApplicationContext().getBaseUrl();
61         }
62         case 2: { // Solution
63
return PentahoSystem.getApplicationContext().getSolutionPath(""); //$NON-NLS-1$
64
}
65       }
66       return null;
67     }
68     
69     public static String JavaDoc applyTemplate(String JavaDoc template, IRuntimeContext context, IParameterResolver resolver) {
70       return applyTemplate(template, new InputProperties(context), resolver);
71     }
72     
73     public static String JavaDoc applyTemplate(String JavaDoc template, IRuntimeContext context) {
74         return applyTemplate(template, new InputProperties(context), null);
75     }
76
77     public static String JavaDoc applyTemplate(String JavaDoc template, IRuntimeContext context, String JavaDoc parameterPatternStr) {
78         Pattern JavaDoc pattern = Pattern.compile( parameterPatternStr );
79         return applyTemplate(template, new InputProperties(context), pattern, null);
80     }
81
82     public static String JavaDoc applyTemplate(String JavaDoc template, Properties JavaDoc inputs, IParameterResolver resolver) {
83         return applyTemplate(template, inputs, parameterExpressionPattern, resolver);
84     }
85
86     /**
87      * Processes a template by processing the parameters declared in the
88      * template. The parameters to be replaced are enclosed in curly brackets.
89      * Parameters can be the input values (as specified by the name of the input
90      * value) or date expressions. Parameters that can not be processed are left
91      * in the template.
92      *
93      * @param template
94      * the template specification.
95      * @param input
96      * the input values communicated as a
97      * {@link java.util.Properties}.
98      * @param locale
99      * the locale to use for the formatting of date expression. If
100      * <tt>null</tt>, the locale for the thread is used. If no
101      * locale for the thread, then the default locale is used.
102      * @throws IllegalArgumentException
103      * if a date expression is illegal
104      * @see DateMath#calculateDateString(Calendar, String)
105      * @see PentahoSystem#getLocale()
106      * @see PentahoSystem#getDefaultLocale()
107      */

108     public static String JavaDoc applyTemplate(String JavaDoc template, Properties JavaDoc inputs, Pattern JavaDoc parameterPattern, IParameterResolver resolver) {
109         StringBuffer JavaDoc results = new StringBuffer JavaDoc();
110         Matcher JavaDoc parameterMatcher = parameterPattern.matcher(template);
111         int copyStart = 0;
112
113         while (parameterMatcher.find()) {
114             int start = parameterMatcher.start();
115             String JavaDoc parameter = parameterMatcher.group(1);
116             String JavaDoc value = null;
117             int pos1 = parameter.indexOf(':');
118             if (pos1 > -1) {
119                 // Allow alternate parameter resolution to be provided by the
120
// component.
121
if (resolver != null) {
122                   int newCopyStart = resolver.resolveParameter(template, parameter, parameterMatcher, copyStart, results);
123                   if (newCopyStart >=0 ) {
124                     copyStart = newCopyStart;
125                     continue;
126                   }
127                 }
128                 StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(parameter, ":"); //$NON-NLS-1$
129
if (tokenizer.countTokens() >= 5) {
130                     // this looks like a data table key
131
parameter = tokenizer.nextToken();
132                     String JavaDoc keyColumn = tokenizer.nextToken();
133                     String JavaDoc keyValue = tokenizer.nextToken();
134                     String JavaDoc valueColumn = tokenizer.nextToken();
135                     StringBuffer JavaDoc defaultValue = new StringBuffer JavaDoc();
136                     defaultValue.append(tokenizer.nextToken());
137                     while (tokenizer.hasMoreTokens()) {
138                         defaultValue.append(':').append(tokenizer.nextToken());
139                     }
140                     // see if we can find this in the data
141
if (inputs instanceof InputProperties) {
142                         value = ((InputProperties) inputs).getProperty(parameter, keyColumn, keyValue, valueColumn, defaultValue.toString());
143                     }
144                 }
145             }
146             if (value == null) {
147                 // TODO support type conversion
148
value = inputs.getProperty(parameter);
149             }
150
151             results.append(template.substring(copyStart, start));
152             copyStart = parameterMatcher.end();
153             if (value == null) {
154                 Matcher JavaDoc dateMatcher = dateExpressionPattern.matcher(parameter);
155
156                 if (dateMatcher.matches()) {
157                     value = DateMath.calculateDateString(null, parameter);
158                 }
159             }
160
161             if (value == null) {
162                 results.append(parameterMatcher.group());
163             } else {
164                 results.append(value);
165             }
166         }
167
168         if (copyStart < template.length()) {
169             results.append(template.substring(copyStart));
170         }
171
172         return results.toString();
173     }
174
175     public static String JavaDoc applyTemplate(String JavaDoc template, String JavaDoc name, String JavaDoc value) {
176
177         String JavaDoc result = template;
178         result = result.replaceAll("\\{" + name + "\\}", value); //$NON-NLS-1$//$NON-NLS-2$
179
return result;
180
181     }
182
183     public static String JavaDoc applyTemplate(String JavaDoc template, String JavaDoc name, String JavaDoc[] value) {
184         if ( value == null ) {
185             return( template );
186         }
187         
188         if ( value.length == 1 ) {
189             return( applyTemplate( template, name, value[0] ) );
190         }
191         
192         int pos = template.indexOf( "{" + name + "}" ); //$NON-NLS-1$ //$NON-NLS-2$
193
if ( pos == -1 ) {
194             return( template );
195         }
196
197         int startPos = template.substring(0, pos).lastIndexOf('&');
198         if ( startPos < 0 ) {
199             startPos = template.substring(0, pos).lastIndexOf('?');
200         }
201         if ( startPos < 0 ) {
202             startPos = 0;
203         }
204         else {
205             startPos += 1;
206         }
207         
208         int endPos = template.substring(pos + name.length()+1).indexOf('&');
209         if ( endPos < 0 ) {
210             endPos = template.substring(pos + name.length()+1).indexOf('#');
211         }
212         if ( endPos < 0 ) {
213             endPos = template.length();
214         }
215         else {
216             endPos += pos + name.length()+1;
217         }
218         
219         String JavaDoc result = template.substring( 0, startPos );
220         String JavaDoc replacePart = template.substring( startPos, endPos );
221         
222         result += replacePart.replaceAll("\\{" + name + "\\}", value[0]); //$NON-NLS-1$ //$NON-NLS-2$
223
for ( int i = 1; i < value.length; ++i ) {
224             result += "&" + replacePart.replaceAll("\\{" + name + "\\}", value[i]); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
225
}
226         
227         result += template.substring( endPos );
228         return result;
229
230     }
231
232     /**
233      * Acts as a facade for a {@link IRuntimeContext} to access the input values
234      * as from a {@link java.util.Properties Properties}. The class only
235      * overrides the {@link #getProperty(String)} method, as its is the only
236      * method used in
237      * {@link TemplateComponent#applyTemplate(String, IRuntimeContext) TemplateComponent.applyTemplate(String, IRuntimeContext)}.
238      */

239     private static class InputProperties extends Properties JavaDoc {
240         private static final long serialVersionUID = 1L;
241
242         Pattern JavaDoc dateExpressionRegexPattern = Pattern.compile(DATE_EXPR_PATTERN);
243
244         private IRuntimeContext context;
245
246         private Set JavaDoc inputs;
247
248         private static final Log logger = LogFactory.getLog(InputProperties.class);
249
250         InputProperties(IRuntimeContext context) {
251             this.context = context;
252             inputs = new HashSet JavaDoc();
253             inputs.addAll(context.getInputNames());
254             inputs.add("$user"); //$NON-NLS-1$
255
inputs.add("$url"); //$NON-NLS-1$
256
inputs.add("$solution"); //$NON-NLS-1$
257
}
258
259         public int size() {
260             if (inputs == null) {
261                 return 0;
262             } else {
263                 return inputs.size();
264             }
265         }
266
267         public String JavaDoc getProperty(String JavaDoc parameter, String JavaDoc keyColumn, String JavaDoc keyValue, String JavaDoc valueColumn, String JavaDoc defaultValue) {
268             if (!context.getInputNames().contains(parameter)) {
269                 // leave the text alone
270
return "{" + parameter + ":" + keyColumn + ":" + keyValue + ":" + valueColumn + ":" + defaultValue + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
271
}
272             Object JavaDoc valueObj = context.getInputParameterValue(parameter);
273             if (valueObj instanceof IPentahoResultSet) {
274                 IPentahoResultSet data = (IPentahoResultSet) valueObj;
275                 // this is slow
276
// TODO implement mapping or sorting here to improve performance
277
int keyColumnNo = data.getMetaData().getColumnIndex(keyColumn);
278                 if (keyValue.indexOf('_') > 0) {
279                     keyValue = keyValue.replace('_', ' ');
280                 }
281                 int valueColumnNo = data.getMetaData().getColumnIndex(valueColumn);
282                 if (keyColumnNo != -1 && valueColumnNo != -1) {
283                     for (int row = 0; row < data.getRowCount(); row++) {
284                         Object JavaDoc thisKey = data.getValueAt(row, keyColumnNo);
285                         if (thisKey != null) {
286                             if (keyValue.equals(thisKey.toString())) {
287                                 // we found the value
288
// TODO support typing here
289
return data.getValueAt(row, valueColumnNo).toString();
290                             }
291                         }
292                     }
293                 }
294             }
295             return defaultValue;
296         }
297
298         public String JavaDoc getProperty(String JavaDoc name) {
299             String JavaDoc value = null;
300             if (inputs == null) {
301                 return null;
302             }
303             if (inputs.contains(name)) {
304               value = TemplateUtil.getSystemInput(name, context);
305               if (value != null) {
306                 return value;
307               }
308                 Object JavaDoc valueObj = context.getInputParameterValue(name);
309                 if (valueObj instanceof String JavaDoc) {
310                     value = (String JavaDoc) valueObj;
311                 } else if (valueObj instanceof Object JavaDoc[]) {
312                     Object JavaDoc values[] = (Object JavaDoc[]) valueObj;
313                     StringBuffer JavaDoc valuesBuffer = new StringBuffer JavaDoc();
314                     // TODO support non-string items
315
// TODO this is assuming that the surrounding 's exist
316
for (int i = 0; i < values.length; i++) {
317                         if (i == 0) {
318                             valuesBuffer.append("'").append(values[i].toString()).append("'"); //$NON-NLS-1$ //$NON-NLS-2$
319
} else {
320                             valuesBuffer.append(",'").append(values[i].toString()).append("'"); //$NON-NLS-1$ //$NON-NLS-2$
321
}
322                     }
323                     String JavaDoc valueStr = valuesBuffer.toString();
324                     value = valueStr.substring(1, valueStr.length() - 1);
325                 } else if (valueObj instanceof IPentahoResultSet) {
326                     IPentahoResultSet rs = (IPentahoResultSet) valueObj;
327                     // See if we can find a column in the metadata with the same
328
// name as the input
329
IPentahoMetaData md = rs.getMetaData();
330                     int columnIdx = -1;
331                     if (md.getColumnCount() == 1) {
332                         columnIdx = 0;
333                     } else {
334                         columnIdx = md.getColumnIndex(new String JavaDoc[] { name });
335                     }
336                     if (columnIdx < 0) {
337                         logger.error(Messages.getErrorString("Template.ERROR_0005_COULD_NOT_DETERMINE_COLUMN")); //$NON-NLS-1$
338
return null;
339                     }
340                     int rowCount = rs.getRowCount();
341                     Object JavaDoc valueCell = null;
342                     StringBuffer JavaDoc valuesBuffer = new StringBuffer JavaDoc();
343                     // TODO support non-string columns
344
for (int i = 0; i < rowCount; i++) {
345                         valueCell = rs.getValueAt(i, columnIdx);
346                         if (i == 0) {
347                             valuesBuffer.append("'").append(valueCell.toString()).append("'"); //$NON-NLS-1$ //$NON-NLS-2$
348
} else {
349                             valuesBuffer.append(",'").append(valueCell.toString()).append("'"); //$NON-NLS-1$ //$NON-NLS-2$
350
}
351                     }
352                     String JavaDoc valueStr = valuesBuffer.toString();
353                     // TODO Assumes that parameter is already surrounded by
354
// quotes.
355
value = valueStr.substring(1, valueStr.length() - 1);
356                 } else if (valueObj != null) {
357                     value = valueObj.toString();
358                 }
359                 // TODO add support for numeric classes
360
} else {
361                 value = super.getProperty(name);
362             }
363             if (value == null) {
364                 Matcher JavaDoc dateMatcher = dateExpressionRegexPattern.matcher(name);
365                 if (dateMatcher.matches()) {
366                     value = DateMath.calculateDateString(null, name);
367                 }
368             } else {
369                 Matcher JavaDoc dateMatcher = dateExpressionRegexPattern.matcher(value);
370                 if (dateMatcher.matches()) {
371                     value = DateMath.calculateDateString(null, value);
372                 }
373             }
374
375             return value;
376         }
377     }
378
379     public static Properties JavaDoc parametersToProperties(IParameterProvider parameterProvider) {
380         Properties JavaDoc properties = new Properties JavaDoc();
381         Iterator JavaDoc names = parameterProvider.getParameterNames();
382         while (names.hasNext()) {
383             String JavaDoc name = (String JavaDoc) names.next();
384             String JavaDoc value = parameterProvider.getStringParameter(name, null);
385             if (value != null) {
386                 properties.put(name, value);
387             }
388         }
389         return properties;
390     }
391
392 }
393
Popular Tags