KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pentaho > ui > component > WidgetGridComponent


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 Aug 23, 2005
14  * @author James Dixon
15  */

16
17 package org.pentaho.ui.component;
18
19 import java.io.File JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.io.OutputStream JavaDoc;
22 import java.io.PrintWriter JavaDoc;
23 import java.io.StringWriter JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.dom4j.Document;
31 import org.dom4j.DocumentHelper;
32 import org.dom4j.Element;
33 import org.dom4j.Node;
34 import org.pentaho.core.connection.IPentahoMetaData;
35 import org.pentaho.core.connection.IPentahoResultSet;
36 import org.pentaho.plugin.jfreechart.DialWidgetDefinition;
37 import org.pentaho.plugin.jfreechart.WidgetDefinition;
38 import org.pentaho.core.runtime.IActionParameter;
39 import org.pentaho.core.runtime.IRuntimeContext;
40 import org.pentaho.core.solution.ActionResource;
41 import org.pentaho.core.solution.IActionResource;
42 import org.pentaho.core.solution.ISolutionEngine;
43 import org.pentaho.core.solution.SimpleOutputHandler;
44 import org.pentaho.core.system.PentahoSystem;
45 import org.pentaho.core.ui.IPentahoUrlFactory;
46 import org.pentaho.plugin.jfreechart.JFreeChartEngine;
47 import org.pentaho.core.util.TemplateUtil;
48 import org.pentaho.core.util.XmlHelper;
49 import org.pentaho.ui.XmlComponent;
50 import org.pentaho.messages.Messages;
51 import org.pentaho.util.logging.ILogger;
52
53 public class WidgetGridComponent extends XmlComponent {
54
55     /**
56      *
57      */

58     private static final long serialVersionUID = -3952161695550067971L;
59
60     private String JavaDoc definitionPath;
61
62     private int widgetWidth;
63
64     private int widgetHeight;
65
66     private String JavaDoc solution = null;
67
68     private String JavaDoc actionPath = null;
69
70     private String JavaDoc actionName = null;
71
72     private String JavaDoc valueItem = null;
73
74     private String JavaDoc nameItem = null;
75
76     private int columns = 0;
77
78     private String JavaDoc instanceId = null;
79
80     private String JavaDoc actionOutput = null;
81
82     private String JavaDoc urlTemplate = null;
83
84     private String JavaDoc style = null;
85
86     private IRuntimeContext context;
87
88     private static final Log logger = LogFactory.getLog(WidgetGridComponent.class);
89
90     public Log getLogger() {
91         return logger;
92     }
93
94     /**
95      * Creates a WidgetGrid
96      * <p>
97      * After creating an instance of this class <CODE>validate</CODE> should
98      * be called.
99      *
100      * @param type
101      * The type of the widget, currently only TYPE_DIAL is supported
102      * @param definitionPath
103      * The path and name of the XML definition of the dial
104      * @param widgetWidth
105      * The width of the image to be created
106      * @param widgetHeight
107      * The height of the image to be created
108      * @param urlFactory
109      * The urlFactory for the content
110      * @param messages
111      * The messages list for any logger messages
112      */

113     public WidgetGridComponent(String JavaDoc definitionPath, IPentahoUrlFactory urlFactory, List JavaDoc messages) {
114         super(urlFactory, messages, null);
115         this.definitionPath = definitionPath;
116         String JavaDoc info[] = PentahoSystem.parseActionString(definitionPath);
117         if (info != null && info.length == 3) {
118             setSourcePath(info[0] + File.separator + info[2]);
119         }
120         setXsl("text/html", "DialWidget.xsl"); //$NON-NLS-1$ //$NON-NLS-2$
121
}
122
123     /**
124      * Sets the width (in pixels) of the widget images that will be created
125      *
126      * @param widgetWidth
127      */

128     public void setWidgetWidth(int widgetWidth) {
129         this.widgetWidth = widgetWidth;
130     }
131
132     /**
133      * Sets the height (in pixels) of the widget images that will be created
134      *
135      * @param widgetHeight
136      */

137     public void setWidgetHeight(int widgetHeight) {
138         this.widgetHeight = widgetHeight;
139     }
140
141     /**
142      * Sets the number of widgets that will be dispayed in a row before another
143      * row of widgets is created
144      *
145      * @param instanceId
146      */

147     public void setColumns(int columns) {
148         this.columns = columns;
149     }
150
151     /**
152      * Sets the instance id for this execution
153      *
154      * @param instanceId
155      * The instance id of the parent object or process
156      */

157     public void setInstanceId(String JavaDoc instanceId) {
158         this.instanceId = instanceId;
159     }
160
161     public boolean setDataAction(String JavaDoc widgetGridDataDefinition) {
162         ActionResource resource = new ActionResource("", IActionResource.SOLUTION_FILE_RESOURCE, "text/xml", //$NON-NLS-1$ //$NON-NLS-2$
163
widgetGridDataDefinition);
164         try {
165             Document dataActionDocument = PentahoSystem.getSolutionRepository(getSession()).getResourceAsDocument(resource);
166             if (dataActionDocument == null) {
167                 return false;
168             }
169             Node dataNode = dataActionDocument.selectSingleNode("widgetgrid/data"); //$NON-NLS-1$
170
solution = XmlHelper.getNodeText("data-solution", dataNode); //$NON-NLS-1$
171
actionPath = XmlHelper.getNodeText("data-path", dataNode); //$NON-NLS-1$
172
actionName = XmlHelper.getNodeText("data-action", dataNode); //$NON-NLS-1$
173
actionOutput = XmlHelper.getNodeText("data-output", dataNode); //$NON-NLS-1$
174
valueItem = XmlHelper.getNodeText("data-value", dataNode); //$NON-NLS-1$
175
nameItem = XmlHelper.getNodeText("data-name", dataNode); //$NON-NLS-1$
176
widgetWidth = (int) XmlHelper.getNodeText("widgetgrid/width", dataActionDocument, 125); //$NON-NLS-1$
177
widgetHeight = (int) XmlHelper.getNodeText("widgetgrid/height", dataActionDocument, 125); //$NON-NLS-1$
178
columns = (int) XmlHelper.getNodeText("widgetgrid/columns", dataActionDocument, 2); //$NON-NLS-1$
179
style = XmlHelper.getNodeText("widgetgrid/style", dataActionDocument); //$NON-NLS-1$
180
} catch (Exception JavaDoc e) {
181             error(Messages.getErrorString("WidgetGrid.ERROR_0003_DEFINITION_NOT_VALID", widgetGridDataDefinition), e); //$NON-NLS-1$
182
return false;
183         }
184         return true;
185     }
186
187     /**
188      * Sets the action to be executed to get the data for the widgets
189      *
190      * @param solution
191      * @param actionPath
192      * @param actionName
193      * @param actionOutput
194      * @param nameItem
195      * @param valueItem
196      */

197     public void setDataAction(String JavaDoc solution, String JavaDoc actionPath, String JavaDoc actionName, String JavaDoc actionOutput, String JavaDoc nameItem, String JavaDoc valueItem) {
198         this.solution = solution;
199         this.actionPath = actionPath;
200         this.actionName = actionName;
201         this.actionOutput = actionOutput;
202         this.valueItem = valueItem;
203         this.nameItem = nameItem;
204     }
205
206     public void setDrillUrlTemplate(String JavaDoc urlTemplate) {
207         this.urlTemplate = urlTemplate;
208     }
209
210     public boolean validate() {
211         return true;
212     }
213
214     public Document getXmlContent() {
215
216         // get the data to populate the widgets
217
IPentahoResultSet resultSet = null;
218         if (solution != null) {
219             resultSet = getActionData();
220         } else {
221             // TODO support other methods of getting data
222
}
223
224         // create the widget to use
225
// load the XML document that defines the dial
226
ActionResource resource = new ActionResource("", IActionResource.SOLUTION_FILE_RESOURCE, "text/xml", //$NON-NLS-1$ //$NON-NLS-2$
227
definitionPath);
228         Document dialDefinition = null;
229         try {
230             dialDefinition = PentahoSystem.getSolutionRepository(getSession()).getResourceAsDocument(resource);
231         } catch (IOException JavaDoc e) {
232         }
233
234         // create a dial definition from the XML definition
235
WidgetDefinition widgetDefinition = new DialWidgetDefinition(dialDefinition, 0, widgetWidth, widgetHeight, getSession());
236
237         return createDials(resultSet, widgetDefinition);
238     }
239
240     protected Document createDials(IPentahoResultSet resultSet, WidgetDefinition widgetDefinition) {
241
242         if (resultSet == null) {
243             error(Messages.getErrorString("WidgetGrid.ERROR_0001_NO_RESULTS_FROM_ACTION")); //$NON-NLS-1$
244
return null;
245         }
246
247         if (valueItem == null) {
248             error(Messages.getErrorString("WidgetGrid.ERROR_0002_NO_VALUE_ITEM")); //$NON-NLS-1$
249
}
250
251         // Create a document that describes the result
252
Document result = DocumentHelper.createDocument();
253         String JavaDoc baseUrl = PentahoSystem.getApplicationContext().getBaseUrl();
254         setXslProperty("baseUrl", baseUrl); //$NON-NLS-1$
255
Element root = result.addElement("widgets"); //$NON-NLS-1$
256

257         IPentahoMetaData metaData = resultSet.getMetaData();
258         // TODO support multiple column headers / row headers
259
// TODO support an iteration across columns for a given row
260

261         // find the column that we have been told to you
262
Object JavaDoc columnHeaders[][] = metaData.getColumnHeaders();
263         int nameColumnNo = -1;
264         int valueColumnNo = -1;
265         for (int idx = 0; idx < columnHeaders[0].length; idx++) {
266             if (columnHeaders[0][idx].toString().equalsIgnoreCase(nameItem)) {
267                 nameColumnNo = idx;
268             }
269             if (columnHeaders[0][idx].toString().equalsIgnoreCase(valueItem)) {
270                 valueColumnNo = idx;
271             }
272         }
273
274         if (nameColumnNo == -1) {
275             // we did not find the specified name column
276
error(Messages.getErrorString("WidgetGrid.ERROR_0004_NAME_COLUMN_MISSING", nameItem)); //$NON-NLS-1$
277
return null;
278         }
279
280         if (valueColumnNo == -1) {
281             // we did not find the specified name column
282
error(Messages.getErrorString("WidgetGrid.ERROR_0005_VALUE_COLUMN_MISSING", valueItem)); //$NON-NLS-1$
283
return null;
284         }
285
286         double value;
287         String JavaDoc name;
288         Object JavaDoc row[] = resultSet.next();
289         while (row != null) {
290             name = row[nameColumnNo].toString();
291             try {
292                 value = Double.parseDouble(row[valueColumnNo].toString());
293                 createDial(value, name, root, widgetDefinition);
294             } catch (Exception JavaDoc e) {
295             }
296
297             row = resultSet.next();
298         }
299         setXslProperty("urlTarget", "pentaho_popup"); //$NON-NLS-1$ //$NON-NLS-2$
300
setXslProperty("columns", Integer.toString(columns)); //$NON-NLS-1$
301
if (style != null) {
302             setXslProperty("style", style); //$NON-NLS-1$
303
}
304         return result;
305     }
306
307     protected void createDial(double value, String JavaDoc name, Element root, WidgetDefinition widgetDefinition) {
308
309         widgetDefinition.setValue(new Double JavaDoc(value));
310
311         StringWriter JavaDoc stringWriter = new StringWriter JavaDoc();
312         PrintWriter JavaDoc printWriter = new PrintWriter JavaDoc(stringWriter);
313
314         // TODO get units from somewhere
315
String JavaDoc units = ""; //$NON-NLS-1$
316
String JavaDoc dialName = ""; //$NON-NLS-1$
317
// create temporary file names
318
String JavaDoc solutionDir = "system/tmp/"; //$NON-NLS-1$
319
String JavaDoc fileNamePrefix = "tmp_pie_"; //$NON-NLS-1$
320
String JavaDoc extension = ".png"; //$NON-NLS-1$
321
String JavaDoc fileName = null;
322         String JavaDoc filePathWithoutExtension = null;
323         try {
324             File JavaDoc file = File.createTempFile(fileNamePrefix, extension, new File JavaDoc(PentahoSystem.getApplicationContext().getFileOutputPath(solutionDir)));
325             file.deleteOnExit();
326             fileName = file.getName();
327             filePathWithoutExtension = solutionDir + fileName.substring(0, fileName.indexOf('.'));
328         } catch (IOException JavaDoc e) {
329             // TODO Auto-generated catch block
330
e.printStackTrace();
331         }
332         JFreeChartEngine.saveChart(widgetDefinition, dialName, units, filePathWithoutExtension, widgetWidth, widgetHeight, JFreeChartEngine.OUTPUT_PNG, printWriter, this);
333
334         Element widgetNode = root.addElement("widget"); //$NON-NLS-1$
335

336         widgetNode.addElement("title").setText(name); //$NON-NLS-1$
337
widgetNode.addElement("units").setText(units); //$NON-NLS-1$
338
widgetNode.addElement("width").setText(Integer.toString(widgetWidth)); //$NON-NLS-1$
339
widgetNode.addElement("height").setText(Integer.toString(widgetHeight)); //$NON-NLS-1$
340
Element valueNode = widgetNode.addElement("value");//$NON-NLS-1$
341
valueNode.setText(Double.toString(value));
342         valueNode.addAttribute("in-image", Boolean.toString(widgetDefinition.getValueFont() != null)); //$NON-NLS-1$
343
root.addElement("image").setText(fileName); //$NON-NLS-1$
344
widgetNode.addElement("image").setText(fileName); //$NON-NLS-1$
345

346         // apply the current data item name to the URL template
347
String JavaDoc drillUrl = TemplateUtil.applyTemplate(urlTemplate, nameItem, name);
348
349         // now apply any parameters to the URL template
350
drillUrl = TemplateUtil.applyTemplate(drillUrl, context);
351
352         widgetNode.addElement("urlDrill").setText(drillUrl); //$NON-NLS-1$
353

354     }
355
356     public void dispose() {
357         if (context != null)
358             context.dispose();
359     }
360
361     protected IPentahoResultSet getActionData() {
362         // create an instance of the solution engine to execute the specified
363
// action
364

365         ISolutionEngine solutionEngine = PentahoSystem.getSolutionEngineInstance(getSession());
366         solutionEngine.setLoggingLevel(ILogger.DEBUG);
367         solutionEngine.init(getSession());
368
369         HashMap JavaDoc parameterProviders = getParameterProviders();
370
371         OutputStream JavaDoc outputStream = null;
372         SimpleOutputHandler outputHandler = null;
373         outputHandler = new SimpleOutputHandler(outputStream, false);
374
375         ArrayList JavaDoc messages = new ArrayList JavaDoc();
376         String JavaDoc processId = this.getClass().getName();
377         context = solutionEngine.execute(solution, actionPath, actionName, processId, false, true, instanceId, false, parameterProviders, outputHandler, null, urlFactory, messages);
378
379         if (actionOutput != null) {
380             if (context.getOutputNames().contains(actionOutput)) {
381                 IActionParameter output = context.getOutputParameter(actionOutput);
382                 IPentahoResultSet results = output.getValueAsResultSet();
383                 if (results != null) {
384                     results = results.memoryCopy();
385                 }
386                 return results;
387             } else {
388                 // this is an error
389
return null;
390             }
391         } else {
392             // return the first list that we find...
393
Iterator JavaDoc it = context.getOutputNames().iterator();
394             while (it.hasNext()) {
395                 IActionParameter output = (IActionParameter) it.next();
396                 if (output.getType().equalsIgnoreCase(IActionParameter.TYPE_RESULT_SET)) {
397                     IPentahoResultSet results = output.getValueAsResultSet();
398                     if (results != null) {
399                         results = results.memoryCopy();
400                     }
401                     return results;
402                 }
403             }
404         }
405         return null;
406     }
407
408 }
409
Popular Tags