001: /*
002: * Copyright (C) 2005 - 2008 JasperSoft Corporation. All rights reserved.
003: * http://www.jaspersoft.com.
004: *
005: * Unless you have purchased a commercial license agreement from JasperSoft,
006: * the following license terms apply:
007: *
008: * This program is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU General Public License version 2 as published by
010: * the Free Software Foundation.
011: *
012: * This program is distributed WITHOUT ANY WARRANTY; and without the
013: * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
014: * See the GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, see http://www.gnu.org/licenses/gpl.txt
018: * or write to:
019: *
020: * Free Software Foundation, Inc.,
021: * 59 Temple Place - Suite 330,
022: * Boston, MA USA 02111-1307
023: *
024: *
025: *
026: *
027: * BeanInspectorPanel.java
028: *
029: * Created on June 19, 2006, 2:57 PM
030: *
031: */
032:
033: package it.businesslogic.ireport.data;
034:
035: import it.businesslogic.ireport.FieldsProviderEditor;
036: import it.businesslogic.ireport.JRField;
037: import it.businesslogic.ireport.ReportClassLoader;
038: import it.businesslogic.ireport.gui.JBTreeCellRenderer;
039: import it.businesslogic.ireport.gui.MainFrame;
040: import it.businesslogic.ireport.gui.ReportQueryDialog;
041: import it.businesslogic.ireport.gui.TreeJRField;
042: import it.businesslogic.ireport.data.hibernate.HQLFieldsReader;
043: import it.businesslogic.ireport.util.Misc;
044: import java.util.ArrayList;
045: import java.util.List;
046: import java.util.Vector;
047: import javax.swing.JTable;
048: import javax.swing.SwingUtilities;
049: import javax.swing.table.DefaultTableModel;
050: import javax.swing.tree.DefaultMutableTreeNode;
051: import javax.swing.tree.DefaultTreeModel;
052: import javax.swing.tree.TreePath;
053: import it.businesslogic.ireport.util.I18n;
054:
055: /**
056: *
057: * @author gtoffoli
058: */
059: public class BeanInspectorPanel extends javax.swing.JPanel implements
060: FieldsProviderEditor {
061:
062: private boolean pathOnDescription = false;
063: private JTable jTableFields = null;
064: private boolean comboVisible = true;
065: private ReportQueryDialog reportQueryDialog = null;
066:
067: /** Creates new form BeanInspectorPanel */
068: public BeanInspectorPanel() {
069: initComponents();
070:
071: DefaultTreeModel dttm = (DefaultTreeModel) jTree1.getModel();
072: DefaultMutableTreeNode root = new DefaultMutableTreeNode();
073: jTree1.setModel(new DefaultTreeModel(root));
074:
075: jTree1.setCellRenderer(new JBTreeCellRenderer());
076:
077: applyI18n();
078: }
079:
080: public void setClassNames(List classNames) {
081: if (classNames == null)
082: return;
083:
084: jComboBox1.removeAllItems();
085: for (int i = 0; i < classNames.size(); ++i) {
086: jComboBox1.addItem(classNames.get(i));
087: }
088:
089: jComboBox1ActionPerformed(null);
090: }
091:
092: /**
093: * Must be used when the combobox is not visible...
094: */
095: public void setClassName(String className) {
096: DefaultMutableTreeNode root = (DefaultMutableTreeNode) jTree1
097: .getModel().getRoot();
098: root.removeAllChildren();
099: jTree1.updateUI();
100: if (className != null && className.trim().length() > 0) {
101: exploreBean(root, className, "");
102: }
103: }
104:
105: /** This method is called from within the constructor to
106: * initialize the form.
107: * WARNING: Do NOT modify this code. The content of this method is
108: * always regenerated by the Form Editor.
109: */
110: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
111: private void initComponents() {
112: java.awt.GridBagConstraints gridBagConstraints;
113:
114: jPanel1 = new javax.swing.JPanel();
115: jLabel1 = new javax.swing.JLabel();
116: jComboBox1 = new javax.swing.JComboBox();
117: jScrollPane1 = new javax.swing.JScrollPane();
118: jTree1 = new javax.swing.JTree();
119: jPanel2 = new javax.swing.JPanel();
120: jButton2 = new javax.swing.JButton();
121: jButton3 = new javax.swing.JButton();
122:
123: setLayout(new java.awt.GridBagLayout());
124:
125: jPanel1.setLayout(new java.awt.GridBagLayout());
126:
127: jLabel1.setText("Bean");
128: gridBagConstraints = new java.awt.GridBagConstraints();
129: gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
130: jPanel1.add(jLabel1, gridBagConstraints);
131:
132: jComboBox1.setMinimumSize(new java.awt.Dimension(51, 22));
133: jComboBox1
134: .addActionListener(new java.awt.event.ActionListener() {
135: public void actionPerformed(
136: java.awt.event.ActionEvent evt) {
137: jComboBox1ActionPerformed(evt);
138: }
139: });
140:
141: gridBagConstraints = new java.awt.GridBagConstraints();
142: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
143: gridBagConstraints.weightx = 1.0;
144: gridBagConstraints.insets = new java.awt.Insets(4, 0, 4, 0);
145: jPanel1.add(jComboBox1, gridBagConstraints);
146:
147: gridBagConstraints = new java.awt.GridBagConstraints();
148: gridBagConstraints.gridx = 0;
149: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
150: gridBagConstraints.weightx = 1.0;
151: add(jPanel1, gridBagConstraints);
152:
153: jTree1.setRootVisible(false);
154: jTree1.addMouseListener(new java.awt.event.MouseAdapter() {
155: public void mouseClicked(java.awt.event.MouseEvent evt) {
156: jTree1MouseClicked1(evt);
157: }
158: });
159:
160: jScrollPane1.setViewportView(jTree1);
161:
162: gridBagConstraints = new java.awt.GridBagConstraints();
163: gridBagConstraints.gridx = 0;
164: gridBagConstraints.gridwidth = 3;
165: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
166: gridBagConstraints.weightx = 1.0;
167: gridBagConstraints.weighty = 1.0;
168: gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 0);
169: add(jScrollPane1, gridBagConstraints);
170:
171: jPanel2.setLayout(new java.awt.GridBagLayout());
172:
173: jButton2.setText("Add selected field(s)");
174: jButton2.addActionListener(new java.awt.event.ActionListener() {
175: public void actionPerformed(java.awt.event.ActionEvent evt) {
176: jButton2ActionPerformed(evt);
177: }
178: });
179:
180: gridBagConstraints = new java.awt.GridBagConstraints();
181: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
182: gridBagConstraints.weightx = 1.0;
183: gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 4);
184: jPanel2.add(jButton2, gridBagConstraints);
185:
186: jButton3.setText("Clear fields list");
187: jButton3.addActionListener(new java.awt.event.ActionListener() {
188: public void actionPerformed(java.awt.event.ActionEvent evt) {
189: jButton2ActionPerformed1(evt);
190: }
191: });
192:
193: gridBagConstraints = new java.awt.GridBagConstraints();
194: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
195: gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 0);
196: jPanel2.add(jButton3, gridBagConstraints);
197:
198: gridBagConstraints = new java.awt.GridBagConstraints();
199: gridBagConstraints.gridx = 0;
200: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
201: gridBagConstraints.weightx = 1.0;
202: gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 0);
203: add(jPanel2, gridBagConstraints);
204:
205: }// </editor-fold>//GEN-END:initComponents
206:
207: private void jButton2ActionPerformed1(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed1
208:
209: DefaultTableModel dtm = (DefaultTableModel) getJTableFields()
210: .getModel();
211: dtm.setRowCount(0);
212:
213: }//GEN-LAST:event_jButton2ActionPerformed1
214:
215: private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
216:
217: // Get all selected paths...
218: if (MainFrame.getMainInstance().getActiveReportFrame() == null
219: || getJTableFields() == null) {
220: return;
221: }
222:
223: DefaultTableModel dtm = (DefaultTableModel) getJTableFields()
224: .getModel();
225:
226: TreePath[] paths = jTree1.getSelectionPaths();
227: if (paths == null)
228: return;
229: for (int i = 0; i < paths.length; ++i) {
230: boolean valid = true;
231: TreePath tp = paths[i];
232:
233: TreeJRField tjrf = (TreeJRField) ((DefaultMutableTreeNode) tp
234: .getLastPathComponent()).getUserObject();
235: String returnType = Misc.getJRFieldType(tjrf.getObj()
236: .getName());
237: it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField(
238: tjrf.getField().getName(), returnType);
239: field.setDescription(tjrf.getField().getDescription());
240: Vector row = new Vector();
241: row.addElement(field);
242: row.addElement(field.getClassType());
243: row.addElement(field.getDescription());
244:
245: if (isComboVisible()
246: && jComboBox1.getSelectedItem() instanceof FieldClassWrapper) {
247: FieldClassWrapper cw = (FieldClassWrapper) jComboBox1
248: .getSelectedItem();
249: field.setName(cw.getFieldName() + "."
250: + field.getDescription());
251: field.setDescription(field.getName());
252: }
253:
254: // Check for duplicates fields...
255: boolean found = fieldAlreadyExists(field);
256: String baseName = field.getName();
257: for (int j = 1; isPathOnDescription() && found; ++j) {
258: field.setName(baseName + "_" + j);
259: found = fieldAlreadyExists(field);
260: }
261:
262: if (!found) {
263: dtm.addRow(row);
264: getJTableFields().getSelectionModel()
265: .addSelectionInterval(
266: getJTableFields().getRowCount() - 1,
267: getJTableFields().getRowCount() - 1);
268: }
269: }
270: }//GEN-LAST:event_jButton2ActionPerformed
271:
272: private void jComboBox1ActionPerformed(
273: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBox1ActionPerformed
274:
275: Object obj = jComboBox1.getSelectedItem();
276: if (obj == null) {
277: setClassName(null);
278: return;
279: }
280: if (obj instanceof String)
281: setClassName((String) obj);
282: if (obj instanceof FieldClassWrapper)
283: setClassName(((FieldClassWrapper) obj).getClassType());
284:
285: }//GEN-LAST:event_jComboBox1ActionPerformed
286:
287: private boolean fieldAlreadyExists(JRField field) {
288: boolean found = false;
289: for (int j = 0; j < getJTableFields().getRowCount(); ++j) {
290: Object ff = getJTableFields().getValueAt(j, 0);
291: if (ff instanceof it.businesslogic.ireport.JRField) {
292: if (((it.businesslogic.ireport.JRField) ff).getName()
293: .equals(field.getName())) {
294: found = true;
295: break;
296: }
297: }
298: }
299:
300: return found;
301: }
302:
303: private void jTree1MouseClicked1(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTree1MouseClicked1
304:
305: if (evt.getClickCount() == 2 && evt.getButton() == evt.BUTTON1) {
306: DefaultMutableTreeNode tn = (DefaultMutableTreeNode) jTree1
307: .getSelectionPath().getLastPathComponent();
308:
309: if (tn.getChildCount() > 0)
310: return;
311:
312: /*if (!jTree1.isCollapsed( jTree1.getSelectionPath() ))
313: {
314: jTree1.collapsePath( jTree1.getSelectionPath() );
315: return;
316: }
317: *
318: */
319: if (tn.getUserObject() instanceof TreeJRField) {
320: TreeJRField jrf = (TreeJRField) tn.getUserObject();
321: if (!jrf.getObj().isPrimitive()
322: && !jrf.getObj().getName().startsWith(
323: "java.lang.")) {
324: exploreBean(tn, jrf.getObj().getName(),
325: isPathOnDescription() ? Misc.nvl(jrf
326: .getField().getDescription(), "")
327: : Misc.nvl(
328: jrf.getField().getName(),
329: ""));
330: }
331: }
332: }
333:
334: }//GEN-LAST:event_jTree1MouseClicked1
335:
336: public void exploreBean(DefaultMutableTreeNode root,
337: String classname, String parentPath) {
338: try {
339:
340: root.removeAllChildren();
341: if (parentPath.length() > 0)
342: parentPath += ".";
343:
344: MainFrame.reportClassLoader.rescanLibDirectory();
345: Class clazz = Class.forName(classname, true,
346: MainFrame.reportClassLoader);
347:
348: java.beans.PropertyDescriptor[] pd = org.apache.commons.beanutils.PropertyUtils
349: .getPropertyDescriptors(clazz);
350: for (int nd = 0; nd < pd.length; ++nd) {
351: String fieldName = pd[nd].getName();
352: if (pd[nd].getPropertyType() != null
353: && pd[nd].getReadMethod() != null) {
354: String returnType = pd[nd].getPropertyType()
355: .getName();
356: it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField(
357: Misc.getJRFieldType(fieldName), returnType);
358: if (isPathOnDescription()) {
359: field.setDescription(parentPath + fieldName);
360: } else {
361: field.setName(parentPath + fieldName);
362: }
363:
364: TreeJRField jtf = new TreeJRField();
365:
366: jtf.setField(field);
367: jtf.setObj(pd[nd].getPropertyType());
368:
369: boolean bChildrens = true;
370: if (pd[nd].getPropertyType().isPrimitive()
371: || pd[nd].getPropertyType().getName()
372: .startsWith("java.lang.")) {
373: bChildrens = false;
374: }
375: root
376: .add(new DefaultMutableTreeNode(jtf,
377: bChildrens));
378: }
379: }
380:
381: jTree1.expandPath(new TreePath(root.getPath()));
382: jTree1.updateUI();
383:
384: } catch (ClassNotFoundException cnf) {
385: javax.swing.JOptionPane
386: .showMessageDialog(
387: this ,
388: I18n
389: .getFormattedString(
390: "messages.BeanInspectorPanel.classNotFoundError",
391: "Class not found error!!\nCheck your classpath and retry!\n{0}",
392: new Object[] { cnf
393: .getMessage() }),
394: I18n.getString("message.title.error",
395: "Error"),
396: javax.swing.JOptionPane.ERROR_MESSAGE);
397: return;
398: } catch (Exception ex) {
399: javax.swing.JOptionPane.showMessageDialog(this , ex
400: .getMessage(), I18n.getString(
401: "message.title.error", "Error"),
402: javax.swing.JOptionPane.ERROR_MESSAGE);
403: return;
404: }
405: }
406:
407: public JTable getJTableFields() {
408: return jTableFields;
409: }
410:
411: public void setJTableFields(JTable jTableFields) {
412: this .jTableFields = jTableFields;
413: }
414:
415: public boolean isComboVisible() {
416: return comboVisible;
417: }
418:
419: public void setComboVisible(boolean comboVisible) {
420: this .comboVisible = comboVisible;
421: jPanel1.setVisible(comboVisible);
422: }
423:
424: public boolean isPathOnDescription() {
425: return pathOnDescription;
426: }
427:
428: public void setPathOnDescription(boolean pathOnDescription) {
429: this .pathOnDescription = pathOnDescription;
430: }
431:
432: // Variables declaration - do not modify//GEN-BEGIN:variables
433: private javax.swing.JButton jButton2;
434: private javax.swing.JButton jButton3;
435: private javax.swing.JComboBox jComboBox1;
436: private javax.swing.JLabel jLabel1;
437: private javax.swing.JPanel jPanel1;
438: private javax.swing.JPanel jPanel2;
439: private javax.swing.JScrollPane jScrollPane1;
440: private javax.swing.JTree jTree1;
441:
442: // End of variables declaration//GEN-END:variables
443:
444: public void applyI18n() {
445: // Start autogenerated code ----------------------
446: jButton2.setText(I18n.getString("beanInspectorPanel.button2",
447: "Add selected field(s)"));
448: jButton3.setText(I18n.getString("beanInspectorPanel.button3",
449: "Clear fields list"));
450: jLabel1.setText(I18n.getString("beanInspectorPanel.label1",
451: "Bean"));
452: // End autogenerated code ----------------------
453: }
454:
455: int lastExecution = 0;
456:
457: public void queryChanged(String newQuery) {
458:
459: lastExecution++;
460: int this Execution = lastExecution;
461: // Execute a thread to perform the query change...
462:
463: String error_msg = "";
464: lastExecution++;
465:
466: int in = lastExecution;
467:
468: if (getReportQueryDialog() == null)
469: return;
470:
471: getReportQueryDialog().getJLabelStatusSQL().setText(
472: "Executing HQL query....");
473: /////////////////////////////
474:
475: try {
476: Thread.currentThread().setContextClassLoader(
477: MainFrame.getMainInstance().getReportClassLoader());
478: } catch (Exception ex) {
479: ex.printStackTrace();
480: }
481:
482: if (in < lastExecution)
483: return; //Abort, new execution requested
484:
485: HQLFieldsReader hqlFR = new HQLFieldsReader(newQuery,
486: getReportQueryDialog().getSubDataset().getParameters());
487:
488: if (in < lastExecution)
489: return; //Abort, new execution requested
490:
491: try {
492: Vector fields = hqlFR.readFields();
493:
494: List columns = new ArrayList();
495: for (int i = 0; i < fields.size(); ++i) {
496: JRField field = (JRField) fields.elementAt(i);
497: columns.add(new Object[] { field, field.getClassType(),
498: field.getDescription() });
499: }
500:
501: Vector v = hqlFR.getNotScalars();
502:
503: if (v.size() == 0)
504: v = null;
505:
506: if (in < lastExecution)
507: return; //Abort, new execution requested
508: setBeanExplorerFromWorker(v, true, true);
509:
510: if (in < lastExecution)
511: return; //Abort, new execution requested
512: setColumnsFromWorker(columns);
513:
514: } catch (Exception ex) {
515: ex.printStackTrace();
516: setBeanExplorerFromWorker(null, true, true);
517: setColumnErrorFromWork("Error: " + ex.getMessage());
518: }
519:
520: getReportQueryDialog().getJLabelStatusSQL().setText("Ready");
521: }
522:
523: /**
524: * Set the columns error message in the ReportQueryDialog....
525: * This is called from a none swing thread, hence all the invoke and
526: * wait magic.
527: * The message is only set if the query string matches the one the
528: * error message is for.
529: *
530: * @param columns The list of columns to set.
531: */
532: protected void setColumnErrorFromWork(final String error_msg) {
533: try {
534:
535: Runnable r = new Runnable() {
536: public void run() {
537: getReportQueryDialog().setColumnsError(error_msg);
538: getReportQueryDialog().getSQLExpressionArea()
539: .requestFocusInWindow();
540: }
541: };
542:
543: if (SwingUtilities.isEventDispatchThread()) {
544: r.run();
545: } else {
546: SwingUtilities.invokeAndWait(r);
547: }
548:
549: } catch (Exception e) {
550: // oh well we got interrupted.
551: }
552: }
553:
554: /**
555: * Set the columns in the ReportQueryDialog....
556: * This is called from a none swing thread, hence all the invoke and
557: * wait magic.
558: * The message is only set if the query string matches the one the
559: * error message is for.
560: *
561: * @param columns The list of columns to set.
562: */
563: protected void setColumnsFromWorker(final List columns) {
564: try {
565:
566: Runnable r = new Runnable() {
567: public void run() {
568: getReportQueryDialog().setColumns(columns);
569: getReportQueryDialog().getSQLExpressionArea()
570: .requestFocusInWindow();
571: }
572: };
573:
574: if (SwingUtilities.isEventDispatchThread()) {
575: r.run();
576: } else {
577: SwingUtilities.invokeAndWait(r);
578: }
579:
580: } catch (Exception e) {
581: // oh well we got interrupted.
582: }
583: }
584:
585: /**
586: * Set the bean explorer
587: *
588: * @param columns The list of columns to set.
589: */
590: protected void setBeanExplorerFromWorker(final Vector v,
591: final boolean pathOnDescription, final boolean useCombo) {
592: try {
593: SwingUtilities.invokeAndWait(new Runnable() {
594: public void run() {
595: Vector v1 = v;
596: if (v1 == null)
597: v1 = new Vector();
598:
599: setComboVisible(useCombo);
600: setPathOnDescription(pathOnDescription);
601: setClassNames(v1);
602:
603: getReportQueryDialog().getSQLExpressionArea()
604: .requestFocusInWindow();
605: getReportQueryDialog().getSQLExpressionArea()
606: .requestFocus();
607: }
608: });
609: } catch (Exception e) {
610: // oh well we got interrupted.
611: e.printStackTrace();
612: }
613: }
614:
615: public ReportQueryDialog getReportQueryDialog() {
616: return reportQueryDialog;
617: }
618:
619: public void setReportQueryDialog(ReportQueryDialog reportQueryDialog) {
620: this.reportQueryDialog = reportQueryDialog;
621: }
622:
623: }
|