001: /*
002: * Copyright 2006-2007 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt.
007: *
008: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
009: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
010: * the license for the specific language governing your rights and limitations.
011: *
012: * Additional Contributor(s): Martin Schmid gridvision engineering GmbH
013: */
014: package org.pentaho.reportdesigner.crm.report.datasetplugin.staticfactory;
015:
016: import com.jgoodies.forms.layout.CellConstraints;
017: import com.jgoodies.forms.layout.FormLayout;
018: import org.jetbrains.annotations.NonNls;
019: import org.jetbrains.annotations.NotNull;
020: import org.jetbrains.annotations.Nullable;
021: import org.jfree.report.ReportDataFactoryException;
022: import org.pentaho.reportdesigner.crm.report.ReportDialog;
023: import org.pentaho.reportdesigner.crm.report.UndoConstants;
024: import org.pentaho.reportdesigner.crm.report.connection.ColumnInfo;
025: import org.pentaho.reportdesigner.crm.report.datasetplugin.jdbc.RowNumberTableModel;
026: import org.pentaho.reportdesigner.crm.report.datasetplugin.properties.PropertyInfo;
027: import org.pentaho.reportdesigner.crm.report.settings.WorkspaceSettings;
028: import org.pentaho.reportdesigner.crm.report.util.JOptionPaneHelper;
029: import org.pentaho.reportdesigner.lib.client.components.CenterPanelDialog;
030: import org.pentaho.reportdesigner.lib.client.components.ComponentFactory;
031: import org.pentaho.reportdesigner.lib.client.components.ProgressDialog;
032: import org.pentaho.reportdesigner.lib.client.i18n.TranslationManager;
033: import org.pentaho.reportdesigner.lib.client.util.ExceptionUtils;
034: import org.pentaho.reportdesigner.lib.client.util.GUIUtils;
035: import org.pentaho.reportdesigner.lib.client.util.TableUtils;
036: import org.pentaho.reportdesigner.lib.client.util.WindowUtils;
037:
038: import javax.swing.*;
039: import javax.swing.event.DocumentEvent;
040: import javax.swing.event.DocumentListener;
041: import javax.swing.table.DefaultTableCellRenderer;
042: import javax.swing.table.TableModel;
043: import java.awt.*;
044: import java.awt.event.ActionEvent;
045: import java.awt.event.ActionListener;
046: import java.lang.reflect.Method;
047: import java.util.ArrayList;
048: import java.util.Collection;
049: import java.util.TreeSet;
050: import java.util.logging.Level;
051: import java.util.logging.Logger;
052:
053: /**
054: * User: Martin
055: * Date: 01.02.2006
056: * Time: 11:48:14
057: */
058: public class StaticFactoryDataSetReportElementConfigurator {
059: @NonNls
060: @NotNull
061: private static final Logger LOG = Logger
062: .getLogger(StaticFactoryDataSetReportElementConfigurator.class
063: .getName());
064:
065: public static boolean showStaticFactoryDataSetReportElementConfigurator(
066: @NotNull
067: ReportDialog parent,
068: @NotNull
069: StaticFactoryDataSetReportElement staticFactoryDataSetReportElement) {
070: StaticFactoryDataSetReportElementConfigurator configurator = new StaticFactoryDataSetReportElementConfigurator(
071: parent, staticFactoryDataSetReportElement);
072: return configurator.ok;
073: }
074:
075: private boolean ok;
076: @NotNull
077: private CenterPanelDialog centerPanelDialog;
078: @NotNull
079: private JTextField queryNameTextField;
080: @NotNull
081: private JTextField classNameTextField;
082: @NotNull
083: private JTextField methodNameTextField;
084: @NotNull
085: private JTable table;
086: @NotNull
087: private ParametersTableModel parametersTableModel;
088: @NotNull
089: private ArrayList<ColumnInfo> columnInfos;
090:
091: private StaticFactoryDataSetReportElementConfigurator(
092: @NotNull
093: final ReportDialog parent,
094: @NotNull
095: final StaticFactoryDataSetReportElement staticFactoryDataSetReportElement) {
096: ok = false;
097:
098: final JButton okButton = new JButton(TranslationManager
099: .getInstance().getTranslation("R", "Button.ok"));
100: okButton.setEnabled(false);
101:
102: JButton cancelButton = new JButton(TranslationManager
103: .getInstance().getTranslation("R", "Button.cancel"));
104:
105: centerPanelDialog = CenterPanelDialog
106: .createDialog(
107: parent,
108: TranslationManager
109: .getInstance()
110: .getTranslation("R",
111: "StaticFactoryDataSetReportElementConfigurator.Title"),
112: CenterPanelDialog.ModalityType.DOCUMENT_MODAL);
113:
114: queryNameTextField = new JTextField(
115: staticFactoryDataSetReportElement.getQueryName());
116: JLabel queryNameLabel = ComponentFactory
117: .createLabel(
118: "R",
119: "StaticFactoryDataSetReportElementConfigurator.QueryNameLabel",
120: queryNameTextField);
121:
122: classNameTextField = new JTextField(
123: staticFactoryDataSetReportElement.getClassName());
124: JLabel classNameLabel = ComponentFactory
125: .createLabel(
126: "R",
127: "StaticFactoryDataSetReportElementConfigurator.ClassNameLabel",
128: classNameTextField);
129:
130: methodNameTextField = new JTextField(
131: staticFactoryDataSetReportElement.getMethodName());
132: final JLabel methodNameLabel = ComponentFactory
133: .createLabel(
134: "R",
135: "StaticFactoryDataSetReportElementConfigurator.MethodNameLabel",
136: methodNameTextField);
137:
138: columnInfos = staticFactoryDataSetReportElement
139: .getColumnInfos();
140: parametersTableModel = new ParametersTableModel(
141: new ArrayList<PropertyInfo>(
142: staticFactoryDataSetReportElement
143: .getParameters()));
144: table = new ParametersTable(parametersTableModel, true);
145: JLabel parametersLabel = ComponentFactory
146: .createLabel(
147: "R",
148: "StaticFactoryDataSetReportElementConfigurator.ParametersLabel",
149: table);
150:
151: JButton previewButton = ComponentFactory
152: .createButton("R",
153: "StaticFactoryDataSetReportElementConfigurator.PreviewButton");
154:
155: @NonNls
156: FormLayout formLayout = new FormLayout(
157: "4dlu, fill:default, 4dlu, fill:default:grow, 4dlu",
158: "4dlu, " + "pref, " + "4dlu, " + "pref, " + "4dlu, "
159: + "pref, " + "4dlu, " + "fill:10dlu:grow, "
160: + "4dlu, " + "pref, " + "4dlu, " + "4dlu");
161: @NonNls
162: CellConstraints cc = new CellConstraints();
163:
164: final JPanel centerPanel = new JPanel(formLayout);
165:
166: centerPanel.add(queryNameLabel, cc.xy(2, 2));
167: centerPanel.add(queryNameTextField, cc.xy(4, 2));
168: centerPanel.add(classNameLabel, cc.xy(2, 4));
169: centerPanel.add(classNameTextField, cc.xy(4, 4));
170: centerPanel.add(methodNameLabel, cc.xy(2, 6));
171: centerPanel.add(methodNameTextField, cc.xy(4, 6));
172:
173: centerPanel.add(parametersLabel, cc.xy(2, 8, "left, top"));
174: centerPanel.add(new JScrollPane(table), cc.xy(4, 8));
175:
176: centerPanel.add(previewButton, cc.xy(4, 10, "right, center"));
177:
178: final Color origForegroundColor = classNameTextField
179: .getForeground();
180: classNameTextField.getDocument().addDocumentListener(
181: new DocumentListener() {
182: public void insertUpdate(@NotNull
183: DocumentEvent e) {
184: checkClass();
185: }
186:
187: public void removeUpdate(@NotNull
188: DocumentEvent e) {
189: checkClass();
190: }
191:
192: public void changedUpdate(@NotNull
193: DocumentEvent e) {
194: checkClass();
195: }
196:
197: private void checkClass() {
198: okButton.setEnabled(false);
199:
200: try {
201: Class.forName(classNameTextField.getText());
202: classNameTextField
203: .setForeground(origForegroundColor);
204: } catch (ClassNotFoundException e) {
205: if (LOG.isLoggable(Level.FINE))
206: LOG
207: .log(
208: Level.FINE,
209: "StaticFactoryDataSetReportElementConfigurator.checkClass ",
210: e);
211: classNameTextField.setForeground(Color.RED);
212: }
213: }
214: });
215:
216: methodNameTextField.getDocument().addDocumentListener(
217: new DocumentListener() {
218: public void insertUpdate(@NotNull
219: DocumentEvent e) {
220: checkMethod();
221: }
222:
223: public void removeUpdate(@NotNull
224: DocumentEvent e) {
225: checkMethod();
226: }
227:
228: public void changedUpdate(@NotNull
229: DocumentEvent e) {
230: checkMethod();
231: }
232:
233: private void checkMethod() {
234: okButton.setEnabled(false);
235:
236: try {
237: Class<?> clazz = Class
238: .forName(classNameTextField
239: .getText());
240: Method[] methods = clazz.getMethods();
241: Method foundMethod = null;
242: for (Method method : methods) {
243: if (TableModel.class
244: .isAssignableFrom(method
245: .getReturnType())
246: && method.getName().equals(
247: methodNameTextField
248: .getText())) {
249: foundMethod = method;
250: break;
251: }
252: }
253: if (foundMethod != null) {
254: methodNameTextField
255: .setForeground(origForegroundColor);
256:
257: fillParameters(foundMethod);
258: } else {
259: methodNameTextField
260: .setForeground(Color.RED);
261: }
262: } catch (ClassNotFoundException e) {
263: if (LOG.isLoggable(Level.FINE))
264: LOG
265: .log(
266: Level.FINE,
267: "StaticFactoryDataSetReportElementConfigurator.checkMethod ",
268: e);
269: methodNameTextField
270: .setForeground(Color.RED);
271: }
272: }
273: });
274:
275: previewButton.addActionListener(new ActionListener() {
276: public void actionPerformed(@NotNull
277: ActionEvent e) {
278: final ProgressDialog progressDialog = ProgressDialog
279: .createProgressDialog(
280: parent,
281: TranslationManager
282: .getInstance()
283: .getTranslation("R",
284: "JDBCConnectionConfigurationPanel.ProgressDialog.Title"),
285: "");
286: Thread t = new Thread(new Runnable() {
287: public void run() {
288: try {
289: TableModel reportDataTableModel = StaticFactoryDataSetReportElement
290: .fetchPreviewDataTableModel(
291: classNameTextField
292: .getText(),
293: methodNameTextField
294: .getText(),
295: getParameters());
296: columnInfos = new ArrayList<ColumnInfo>();
297: for (int i = 0; i < reportDataTableModel
298: .getColumnCount(); i++) {
299: columnInfos.add(new ColumnInfo("",
300: reportDataTableModel
301: .getColumnName(i),
302: reportDataTableModel
303: .getColumnClass(i)));
304: }
305:
306: ExceptionUtils
307: .disposeDialogInEDT(progressDialog);
308:
309: showPreviewDialog(centerPanel,
310: reportDataTableModel);
311: okButton.setEnabled(true);
312: } catch (ReportDataFactoryException e1) {
313: if (LOG.isLoggable(Level.FINE))
314: LOG
315: .log(
316: Level.FINE,
317: "StaticFactoryDataSetReportElementConfigurator.actionPerformed ",
318: e1);
319: ExceptionUtils
320: .disposeDialogInEDT(progressDialog);
321: JOptionPaneHelper
322: .showMessageDialog(
323: centerPanel,
324: TranslationManager
325: .getInstance()
326: .getTranslation(
327: "R",
328: "StaticFactoryDataSetReportElementConfigurator.PreviewErrorMessage"),
329: TranslationManager
330: .getInstance()
331: .getTranslation(
332: "R",
333: "Error.Title"),
334: JOptionPaneHelper.ERROR_MESSAGE,
335: CenterPanelDialog.ModalityType.DOCUMENT_MODAL);
336: okButton.setEnabled(false);
337: }
338:
339: }
340: });
341:
342: t.setDaemon(true);
343: t.setPriority(Thread.NORM_PRIORITY - 1);
344: t.start();
345:
346: if (t.isAlive()) {
347: progressDialog.setVisible(true);
348: }
349: }
350: });
351:
352: centerPanelDialog.setCenterPanel(centerPanel);
353: centerPanelDialog.setButtons(okButton, cancelButton, okButton,
354: cancelButton);
355:
356: cancelButton.addActionListener(new ActionListener() {
357: public void actionPerformed(@NotNull
358: ActionEvent e) {
359: ok = false;
360: centerPanelDialog.dispose();
361: }
362: });
363:
364: okButton.addActionListener(new ActionListener() {
365: public void actionPerformed(@NotNull
366: ActionEvent e) {
367: parent.getUndo().startTransaction(
368: UndoConstants.CONNECTION_SETTINGS);
369: staticFactoryDataSetReportElement
370: .setColumnInfos(new ArrayList<ColumnInfo>(
371: columnInfos));
372: staticFactoryDataSetReportElement
373: .setQueryName(classNameTextField.getText());
374: staticFactoryDataSetReportElement
375: .setClassName(classNameTextField.getText());
376: staticFactoryDataSetReportElement
377: .setMethodName(methodNameTextField.getText());
378: staticFactoryDataSetReportElement
379: .setParameters(new TreeSet<PropertyInfo>(
380: parametersTableModel.getProperties()));
381:
382: parent.getUndo().endTransaction();
383:
384: parent
385: .getWorkspaceSettings()
386: .storeDialogBounds(centerPanelDialog,
387: "StaticFactoryDataSetReportElementConfigurator");
388: ok = true;
389: centerPanelDialog.dispose();
390: }
391: });
392:
393: if (!parent.getWorkspaceSettings().restoreDialogBounds(
394: centerPanelDialog,
395: "StaticFactoryDataSetReportElementConfigurator")) {
396: centerPanelDialog.pack();
397: GUIUtils.ensureMinimumDialogSize(centerPanelDialog, 400,
398: 400);
399: }
400: WindowUtils.setLocationRelativeTo(centerPanelDialog, parent);
401:
402: centerPanelDialog.setVisible(true);
403: }
404:
405: @NotNull
406: private Collection<PropertyInfo> getParameters() {
407: return new ArrayList<PropertyInfo>(parametersTableModel
408: .getProperties());
409: }
410:
411: private void fillParameters(@NotNull
412: Method method) {
413: Class<?>[] types = method.getParameterTypes();
414: if (types.length == parametersTableModel.getProperties().size()) {
415: for (int i = 0; i < types.length; i++) {
416: Class<?> type = types[i];
417: PropertyInfo info = parametersTableModel.getProperty(i);
418: if (info != null) {
419: Class<?> type2 = info.getClazz();
420: //noinspection ObjectEquality
421: if (type != type2) {
422: refillModel(types);
423: break;
424: }
425: }
426: }
427: } else {
428: refillModel(types);
429: }
430: }
431:
432: private void refillModel(@NotNull
433: Class<?>[] types) {
434: ArrayList<PropertyInfo> propertyInfos = new ArrayList<PropertyInfo>();
435: for (int i = 0; i < types.length; i++) {
436: Class<?> type = types[i];
437: propertyInfos.add(new PropertyInfo("staticfactory.param"
438: + (i + 1), type, null));//NON-NLS
439: }
440: parametersTableModel = new ParametersTableModel(propertyInfos);
441: table.setModel(parametersTableModel);
442: }
443:
444: private void showPreviewDialog(@NotNull
445: Component parent, @NotNull
446: TableModel reportDataTableModel) {
447: final WorkspaceSettings workspaceSettings = WorkspaceSettings
448: .getInstance();
449: final CenterPanelDialog centerPanelDialog = CenterPanelDialog
450: .createDialog(
451: parent,
452: TranslationManager
453: .getInstance()
454: .getTranslation("R",
455: "WizardPageSQLQuery.PreviewDialog.Title"),
456: CenterPanelDialog.ModalityType.DOCUMENT_MODAL);
457:
458: final JPanel centerPanel = new JPanel(new BorderLayout());
459: JTable table = new JTable(reportDataTableModel);
460: JTable rowHeaderTable = new JTable(new RowNumberTableModel(
461: reportDataTableModel.getRowCount()));
462: rowHeaderTable.setEnabled(false);
463: rowHeaderTable.getColumnModel().getColumn(0).setCellRenderer(
464: new DefaultTableCellRenderer() {
465: @NotNull
466: public Component getTableCellRendererComponent(
467: @NotNull
468: JTable table, @Nullable
469: Object value, boolean isSelected,
470: boolean hasFocus, int row, int column) {
471: JLabel tableCellRendererComponent = (JLabel) super
472: .getTableCellRendererComponent(table,
473: value, isSelected, hasFocus,
474: row, column);
475: tableCellRendererComponent
476: .setHorizontalAlignment(JLabel.TRAILING);
477: tableCellRendererComponent
478: .setBackground(centerPanel
479: .getBackground());
480: return tableCellRendererComponent;
481: }
482: });
483: rowHeaderTable.setGridColor(centerPanel.getBackground()
484: .darker());
485: rowHeaderTable.setBorder(BorderFactory.createMatteBorder(1, 0,
486: 0, 0, centerPanel.getBackground().darker()));
487:
488: JViewport viewport = new JViewport();
489: viewport.setPreferredSize(new Dimension(40, 100));
490: viewport.setView(rowHeaderTable);
491: table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
492: TableUtils.resizeAllColumns(table, 200);
493:
494: JScrollPane scrollPane = new JScrollPane(table);
495: scrollPane.setRowHeader(viewport);
496: centerPanel.add(scrollPane, BorderLayout.CENTER);
497: centerPanelDialog.setCenterPanel(centerPanel);
498: JButton closeButton = ComponentFactory.createButton("R",
499: "WizardPageSQLQuery.Close");
500: closeButton.addActionListener(new ActionListener() {
501: public void actionPerformed(@NotNull
502: ActionEvent e) {
503: workspaceSettings.storeDialogBounds(centerPanelDialog,
504: "WizardPageSQLQuery.PreviewDialog");
505: centerPanelDialog.dispose();
506: }
507: });
508: centerPanelDialog.setButtons(closeButton, closeButton,
509: CenterPanelDialog.ButtonAlignment.CENTER, closeButton);
510:
511: if (!workspaceSettings.restoreDialogBounds(centerPanelDialog,
512: "WizardPageSQLQuery.PreviewDialog")) {
513: centerPanelDialog.pack();
514: }
515:
516: WindowUtils.setLocationRelativeTo(centerPanelDialog, parent);
517: centerPanelDialog.setVisible(true);
518: }
519: }
|