/*
 * ReportQueryFrame.java
 *
 *  iReport  --  Visual designer for generating JasperReports Documents
 *  Copyright (C) 2002-2003  Giulio Toffoli gt@businesslogic.it
 *
 *  This program is free software; you can redistribute  and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Giulio Toffoli
 *  Via T.Aspetti, 233
 *  35100 Padova ITALY
 *  gt@businesslogic.it
 *
 *
 * Created on 27 maggio 2003, 19.47
 */

package it.businesslogic.ireport.gui;
import bsh.EvalError;
import it.businesslogic.ireport.*;
import it.businesslogic.ireport.JRParameter;
import it.businesslogic.ireport.util.*;
import java.io.FileReader;
import java.io.FileWriter;
import javax.swing.table.*;
import javax.swing.*;
import java.util.*;
import java.sql.*;
import bsh.Interpreter;
import it.businesslogic.ireport.gui.sheet.Tag;
import it.businesslogic.ireport.hibernate.HQLFieldsReader;

import javax.swing.event.*;
import javax.swing.tree.*;
import java.awt.datatransfer.*;
import java.io.File;
import net.sf.jasperreports.engine.design.JRDesignExpression;
import net.sf.jasperreports.engine.design.JRDesignQuery;

/** 
 * A dialog which allows the user to enter a SQL query and then choose the
 * fields to use in the report.
 *
 * @author <a href="mailto:gt78@users.sourceforge.net">Giulio Toffoli</a>
 * @author <a href="mailto:phenderson@users.sourceforge.net">Peter Henderson</a>
 */
public class ReportQueryDialog extends javax.swing.JDialog implements ClipboardOwner {
    
    protected static String standard_types[]= new String[]{
        "java.lang.String",
	"java.lang.Object",
	"java.lang.Boolean",
	"java.lang.Byte",
	"java.util.Date",
	"java.sql.Timestamp",
	"java.sql.Time",
	"java.lang.Double",
	"java.lang.Float",
	"java.lang.Integer",
	"java.io.InputStream",
	"java.lang.Long",
	"java.lang.Short",
	"java.math.BigDecimal"    
    };
    
    public FieldReader readerThread = null;
    public static int num = 1;
    
    private JLabel getJLabelStatusSQL()
    {
        return this.jLabelStatusSQL;
    }
    
    /** Creates new form ReportQueryFrame */
    public ReportQueryDialog(java.awt.Frame parent, boolean modal) {
        
        super(parent, modal);
        initComponents();
        this.setSize(520, 500);
        Misc.centerFrame(this);
        
        stoppedChanging.setRepeats(false);
        
        DefaultTreeModel dttm = (DefaultTreeModel)jTree1.getModel();
        DefaultMutableTreeNode root = new DefaultMutableTreeNode();
        jTree1.setModel(new DefaultTreeModel( root ));
        
        jTree1.setCellRenderer( new JBTreeCellRenderer());
        
        jRSQLExpressionArea1.getDocument().addDocumentListener( new DocumentListener() {
            public void changedUpdate(DocumentEvent e) {
                if(isSettingSQLExpression)return;
                //okButton.setEnabled(false);
                stoppedChanging.restart();
            }
            public void insertUpdate(DocumentEvent e) {
                if(isSettingSQLExpression)return;
                //okButton.setEnabled(false);
                stoppedChanging.restart();
            }
            public void removeUpdate(DocumentEvent e) {
                if(isSettingSQLExpression)return;
                //okButton.setEnabled(false);
                stoppedChanging.restart();
            }
        } );
        
        setColumnsError( "Please open a report." );
        if (MainFrame.getMainInstance().getProperties().getProperty("beanClass") != null)
        {
            jTextFieldBeanClass1.setText( MainFrame.getMainInstance().getProperties().getProperty("beanClass") +"");
        }
        
        jComboBoxQueryType.addItem( new Tag("sql","SQL"));
        jComboBoxQueryType.addItem( new Tag("hql","Hibernate Query Language (HQL)"));
        jComboBoxQueryType.addItem( new Tag("xPath","XPath"));
        
        okButton.setEnabled(false);
    }
    
    /**
     * A timer to detect when the SQL expression area has not been changed, for
     * a short moment. This is to prevent the database being hit with every
     * with every key press.
     */
    javax.swing.Timer stoppedChanging = new javax.swing.Timer( 500, new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            if( automaticlyReadFieldsCheckBox.isSelected() ) {
                processQueryChanged( jRSQLExpressionArea1.getText().trim() );
            }
        }
    } );
    
    
    /**
     * Given a database query string, extract the database columns, then display
     * them. If there was a problem loading the list of columns, show an error
     * panel which contains the reason why.
     *
     * @param query The SQL query string, which can contain JasperReports parameters. 
     */
    private void processQueryChanged( String query ) {
        if (subDataset == null) {
            setColumnsError( "Please open a report." );
            return;
        }
        
        if (query.length() == 0) {
            setColumnsError( "You must insert a valid query first" );
            return;
        }

        IReportConnection conn = (IReportConnection)MainFrame.getMainInstance().getProperties().get("DefaultConnection");
        
        Object obj = jComboBoxQueryType.getSelectedItem();
        String queryLanguage = "sql";
        if (obj != null && obj instanceof Tag) 
        {
            queryLanguage = ""+((Tag)obj).getValue();
        }
        else
        {
            queryLanguage = ""+obj;
        }      
        
        if (queryLanguage.equals("sql") && (conn == null || !conn.isJDBCConnection()) ) {
             setColumnsError( "The active connection is not of type JDBC. Activate a JDBC connection first." );
             return;
        }
                
        try {
            // Run the query in the backgroud as it is not quick.
            if (readerThread != null && readerThread.isAlive())
            {
                readerThread.interrupt();
            }
        } catch (Throwable ex) {
            ex.printStackTrace();

        }

        
        
        readerThread = new FieldReader(query, conn, queryLanguage);
        readerThread.start();
    }
    
    
    /**
     * A Thread class to extract field names from a SQL query.
     *
     */
    class FieldReader extends Thread {
        String src_query;
        String src_query_language = "sql";
        IReportConnection conn;
       
        /**
         * ctor.
         * @param query The query to read the field from
         * @param conn The IRport DB connection to use.
         */
        public FieldReader(String query, IReportConnection conn) {
            this(query, conn, "sql");
        }
        
        /**
         * ctor.
         * @param query The query to read the field from
         * @param conn The IRport DB connection to use.
         */
        public FieldReader(String query, IReportConnection conn, String query_language) {
            src_query=query;
            this.conn=conn;
            this.src_query_language = query_language;
        }
        
        
        
        /**
         * Set the fields table data to the supplied data.
         * This is called from a none swing thread, hence all the invoke and
         * wait magic.
         * The columns are only set if the query string matches the one the 
         * results are for.
         *
         * @param columns The list of columns to set.
         */
        private void setColumnsFromWorker( final List columns ) {
            try {
                SwingUtilities.invokeAndWait( new Runnable() {
                    public void run() {
                        String str = jRSQLExpressionArea1.getText().trim();
                        if( str.compareTo(src_query)==0 ) {
                            setColumns( columns );
                        }
                    }
                } );
            } catch(Exception e) {
                // oh well we got interrupted.
            }
        }

        /**
         * Set the columns error message.
         * This is called from a none swing thread, hence all the invoke and
         * wait magic.
         * The message is only set if the query string matches the one the 
         * error message is for.
         *
         * @param columns The list of columns to set.
         */
        private void setColumnErrorFromWork( final String error_msg ) {
            try {
                SwingUtilities.invokeAndWait( new Runnable() {
                    public void run() {
                        String str = jRSQLExpressionArea1.getText().trim();
                        if( str.compareTo(src_query)==0 ) {
                            setColumnsError( error_msg );
                        }
                    }
                } );
            } catch(Exception e) {
                // oh well we got interrupted.
            }
        }
        
        public String interpretQuery()
        {
            
            String query = this.src_query;
            try {
                Interpreter interpreter = prepareExpressionEvaluator();

                // look for parameters in the query and replace them with default values.
                // parameters look something like 
                // $P{QuoteGroupID}
                // or 
                // $P!{OrderByClause}
                java.util.List queryParams = new ArrayList();
                Enumeration enumParams = subDataset.getParameters().elements();
                while( enumParams.hasMoreElements() ) {
                    it.businesslogic.ireport.JRParameter parameter = (it.businesslogic.ireport.JRParameter)enumParams.nextElement();

                    String p1 = "$P{" + parameter.getName() + "}";
                    String p2 = "$P!{" + parameter.getName() + "}";

                    // evaluate the Default expression value
                    
                    // Integer expID = (Integer)parameterNameToExpressionID.get(parameter.getName());
                    
                    Object defValue;
                    if(  parameter.getDefaultValueExpression() != null &&  !parameter.getDefaultValueExpression().equals("") ) {
                        defValue = recursiveInterpreter( interpreter, parameter.getDefaultValueExpression(), subDataset.getParameters());
                        // interpreter.eval("bshCalculator.evaluate(" + expID.intValue() + ")");
                    } else {
                        // this param does not have a default value.
                        defValue = null;
                    }


                    int ip1 = query.indexOf(p1);
                    while( ip1!=-1 ) {
                        // String replacement, Altering the SQL statement.
                        if( defValue==null ) {
                            throw new IllegalArgumentException("Please set a " +
                                "default value for the parameter '" 
                                + parameter.getName() + "'" );
                        }

                        String before = query.substring(0, ip1);
                        String after = query.substring(ip1+p1.length());
                        if (parameter.getClassType().equals("java.lang.String"))
                        {
                            String stt = defValue.toString();
                            stt = it.businesslogic.ireport.util.Misc.string_replace("''","'", stt);
                            query = before + "'" + stt + "'" + after;
                        }
                        else query = before + "" + defValue.toString() + "" + after;
                        
                        ip1 = query.indexOf(p1);
                    }

                    int ip2 = query.indexOf(p2);
                    while( ip2!=-1 ) {
                        // String replacement, Altering the SQL statement.
                        if( defValue==null ) {
                            throw new IllegalArgumentException("Please set a " +
                                "default value for the parameter '" 
                                + parameter.getName() + "'" );
                        }

                        String before = query.substring(0, ip2);
                        String after = query.substring(ip2+p2.length());
                        query = before + "" + defValue.toString() + "" + after;
                        ip2 = query.indexOf(p2);
                    }
                }
            
                return query;
            } catch (Exception ex)
            {
                javax.swing.JOptionPane.showMessageDialog(null, ex.getMessage());
                return "";
            }
        }
        
        public void run() {
            
            if (this.src_query_language == null || this.src_query_language.equals("sql") )
            {
                runSQL();
            }
            else if ( this.src_query_language.equals("hql"))
            {
                runHQL();
            }
        }
        
        
        /**
         * Execution of a HQL query...
         */
        public void runHQL() {
            String error_msg = "";
            num++;
            getJLabelStatusSQL().setText("Executing HQL query....");
            /////////////////////////////
            
            Thread.currentThread().setContextClassLoader( MainFrame.getMainInstance().getReportClassLoader());
            
            HQLFieldsReader hqlFR = new HQLFieldsReader(this.src_query, getSubDataset().getParameters());
            
            try {
                Vector fields = hqlFR.readFields();
                
                List columns = new ArrayList();
                for (int i=0; i<fields.size(); ++i)
                {
                    JRField field = (JRField)fields.elementAt(i);
                    columns.add( new Object[]{field, field.getClassType(), field.getDescription()} );
                }
                
                setColumnsFromWorker(columns);
                
            } catch (Exception ex)
            {
                ex.printStackTrace();
                setColumnErrorFromWork( "Error: " +  ex.getMessage() );
            }
            getJLabelStatusSQL().setText("Ready");
            /////////////////////
        }
        
        
        
        
        public void runSQL() {
            String error_msg = "";
            num++;
            int in = num;
            getJLabelStatusSQL().setText("Executing SQL query....");
            
            Connection con = null;
            PreparedStatement ps = null;
            try {
                // Prepare the parameter expression evaluator.
                // Cannot cache this as user may have altered the parameters. (this 
                // dialog is not modal.
                
                String query = this.src_query;
                
                
                Interpreter interpreter = prepareExpressionEvaluator();

                // look for parameters in the query and replace them with default values.
                // parameters look something like 
                // $P{QuoteGroupID}
                // or 
                // $P!{OrderByClause}
                java.util.List queryParams = new ArrayList();
                Enumeration enumParams = subDataset.getParameters().elements();
                while( enumParams.hasMoreElements() ) {
                    it.businesslogic.ireport.JRParameter parameter = (it.businesslogic.ireport.JRParameter)enumParams.nextElement();

                    String p1 = "$P{" + parameter.getName() + "}";
                    String p2 = "$P!{" + parameter.getName() + "}";

                    // evaluate the Default expression value
                    //Integer expID = (Integer)parameterNameToExpressionID.get(parameter.getName());
                    //Object defValue;
                    //if( expID!=null ) {
                    //    defValue = interpreter.eval("bshCalculator.evaluate(" + expID.intValue() + ")");
                    //} else {
                        // this param does not have a default value.
                    //    defValue = null;
                    //}
                    
                    Object defValue;
                    if(  parameter.getDefaultValueExpression() != null &&  !parameter.getDefaultValueExpression().equals("") ) {
                        
                        defValue = recursiveInterpreter( interpreter, parameter.getDefaultValueExpression(), subDataset.getParameters());
                        //defValue = interpreter.eval( parameter.getDefaultValueExpression() );
                        // interpreter.eval("bshCalculator.evaluate(" + expID.intValue() + ")");
                    } else {
                        // this param does not have a default value.
                        defValue = null;
                    }


                    int ip1 = query.indexOf(p1);
                    while( ip1!=-1 ) {
                        // add a query parameter
                        if( defValue==null ) {
                            throw new IllegalArgumentException("Please set a " +
                            "default value for the parameter '" + 
                            parameter.getName() + "'" );
                        }

                        String before = query.substring(0, ip1);
                        String after = query.substring(ip1+p1.length());
                        query = before + " ? " + after;
                        queryParams.add( defValue );
                        ip1 = query.indexOf(p1);
                    }

                    int ip2 = query.indexOf(p2);
                    while( ip2!=-1 ) {
                        // String replacement, Altering the SQL statement.
                        if( defValue==null ) {
                            throw new IllegalArgumentException("Please set a " +
                                "default value for the parameter '" 
                                + parameter.getName() + "'" );
                        }

                        String before = query.substring(0, ip2);
                        String after = query.substring(ip2+p2.length());
                        query = before + "" + defValue.toString() + "" + after;
                        ip2 = query.indexOf(p2);
                    }
                }
                
                con = conn.getConnection();
                
                if (in < num) return;
                ps = con.prepareStatement( query );
                for(int pc=0; pc<queryParams.size(); pc++ ) {
                    ps.setObject(pc+1, queryParams.get(pc) );
                }
                
                // Some JDBC drivers don't supports this method...
                try { ps.setFetchSize(0); } catch(Exception e ) {}
                
                
                ResultSet rs = ps.executeQuery();
                
                if (in < num) return;
                
                ResultSetMetaData rsmd = rs.getMetaData();

                if (in < num) return;
                
                List columns = new ArrayList();
                for (int i=1; i <=rsmd.getColumnCount(); ++i) {
                    it.businesslogic.ireport.JRField field = 
                        new it.businesslogic.ireport.JRField(
                            rsmd.getColumnLabel(i), 
                            Misc.getJdbcTypeClass(rsmd, i) );
                    columns.add( new Object[]{field, field.getClassType()} );
                }

                setColumnsFromWorker(columns);
                getJLabelStatusSQL().setText("Ready");
                return;
            } catch( IllegalArgumentException ie ) {
                error_msg = ie.getMessage();
                getJLabelStatusSQL().setText("Ready");
            } catch (NoClassDefFoundError ex) {
            	ex.printStackTrace();
                error_msg = "NoClassDefFoundError!!\nCheck your classpath!";
                getJLabelStatusSQL().setText("Ready");
            } catch (java.sql.SQLException ex) {
                error_msg = "SQL problems:\n"+ex.getMessage();
            } catch (Exception ex) {
                ex.printStackTrace();
                error_msg = "General problem:\n"+ex.getMessage()+
                    "\n\nCheck username and password; is the DBMS active ?!";
                getJLabelStatusSQL().setText("Ready");
            } finally {
                if(ps!=null) try { ps.close(); } catch(Exception e ) {}
                if(con !=null) try { con.close(); } catch(Exception e ) {}
            }
            getJLabelStatusSQL().setText("Ready");
            setColumnErrorFromWork( error_msg );
        }
    }
    
    
    
    
    
    
    /**
     * Shows the list of columns.
     * If the column error message label is visible remove it first.
     *
     * @param cols A List Object[], for the fields.
     */
    private void setColumns( final List cols ) {
        
        columnsErrorMsgLabel.setText( "" );
        jPanel2.remove( columnsErrorScrollPane );
        jPanel2.add( columnsScrollPane, java.awt.BorderLayout.CENTER );
        jPanel2.revalidate();
        
        
        javax.swing.table.DefaultTableModel dtm =  (javax.swing.table.DefaultTableModel)jTableFields.getModel();
        dtm.getDataVector().clear();
        for(int i=0; i<cols.size(); i++) {
            Object [] row = (Object[])cols.get(i);
            dtm.addRow( row );
        }
        
        // Select all the fields so the new user does not get confused, when
        // they press OK. As only the selected fields are actually saved to the
        // report
        jTableFields.selectAll();
        
        okButton.setEnabled( true );
    }
    
    /**
     * Replace the columns list with a label that contains the reason why
     * columns cannot be loaded.
     *
     * @param msg The error message to display, can be in HTML.
     */
    private void setColumnsError( final String msg ) {
        columnsErrorMsgLabel.setText( msg );
        jPanel2.remove( columnsScrollPane );
        jPanel2.add( columnsErrorScrollPane, java.awt.BorderLayout.CENTER );
        jPanel2.revalidate();
        columnsErrorMsgLabel.repaint();
        
        //okButton.setEnabled(false);
    }
    
    
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jSplitPane1 = new javax.swing.JSplitPane();
        jPanel1 = new javax.swing.JPanel();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanelSQL = new javax.swing.JPanel();
        jRSQLExpressionArea1 = new it.businesslogic.ireport.gui.JRSQLExpressionArea();
        jPanel7 = new javax.swing.JPanel();
        automaticlyReadFieldsCheckBox = new javax.swing.JCheckBox();
        readFieldsButton = new javax.swing.JButton();
        exportQueryButton = new javax.swing.JButton();
        jLabelStatusSQL = new javax.swing.JLabel();
        jPanel14 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jComboBoxQueryType = new javax.swing.JComboBox();
        jPanel16 = new javax.swing.JPanel();
        jButtonLoadQuery = new javax.swing.JButton();
        jButtonSaveQuery = new javax.swing.JButton();
        jPanel5 = new javax.swing.JPanel();
        jTextFieldBeanClass = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jButtonReadBeanAttributes = new javax.swing.JButton();
        jPanel10 = new javax.swing.JPanel();
        jPanel8 = new javax.swing.JPanel();
        jTextFieldBeanClass1 = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        jButtonReadBeanAttributes3 = new javax.swing.JButton();
        jPanel11 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTree1 = new javax.swing.JTree();
        jPanel12 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jPanel13 = new javax.swing.JPanel();
        jSeparator1 = new javax.swing.JSeparator();
        jPanel6 = new javax.swing.JPanel();
        jButton2 = new javax.swing.JButton();
        jPanel15 = new javax.swing.JPanel();
        jButton3 = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        columnsScrollPane = new javax.swing.JScrollPane();
        jTableFields = new javax.swing.JTable();
        jPanel3 = new javax.swing.JPanel();
        jPanel4 = new javax.swing.JPanel();
        okButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        jPanel9 = new javax.swing.JPanel();
        columnsErrorScrollPane = new javax.swing.JScrollPane();
        columnsErrorMsgLabel = new javax.swing.JLabel();

        setTitle("Report query");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                closeDialog(evt);
            }
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });

        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPane1.setResizeWeight(0.5);
        jPanel1.setLayout(new java.awt.BorderLayout());

        jPanel1.setMinimumSize(new java.awt.Dimension(10, 100));
        jPanel1.setPreferredSize(new java.awt.Dimension(10, 350));
        jTabbedPane1.setMinimumSize(new java.awt.Dimension(154, 350));
        jTabbedPane1.setPreferredSize(new java.awt.Dimension(154, 350));
        jPanelSQL.setLayout(new java.awt.BorderLayout());

        jPanelSQL.setMinimumSize(new java.awt.Dimension(1, 100));
        jPanelSQL.setPreferredSize(new java.awt.Dimension(1, 350));
        jRSQLExpressionArea1.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        jRSQLExpressionArea1.setMinimumSize(new java.awt.Dimension(661, 200));
        jRSQLExpressionArea1.setPreferredSize(new java.awt.Dimension(661, 340));
        jPanelSQL.add(jRSQLExpressionArea1, java.awt.BorderLayout.CENTER);

        jPanel7.setLayout(new java.awt.GridBagLayout());

        automaticlyReadFieldsCheckBox.setSelected(true);
        automaticlyReadFieldsCheckBox.setText("Automatically Retrieve Fields");
        automaticlyReadFieldsCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                automaticlyReadFieldsCheckBoxActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(2, 5, 2, 0);
        jPanel7.add(automaticlyReadFieldsCheckBox, gridBagConstraints);

        readFieldsButton.setText("Read Fields");
        readFieldsButton.setEnabled(false);
        readFieldsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                readFieldsButtonActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(2, 10, 2, 0);
        jPanel7.add(readFieldsButton, gridBagConstraints);

        exportQueryButton.setText("Send to clipboard");
        exportQueryButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exportQueryButtonActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(2, 10, 2, 0);
        jPanel7.add(exportQueryButton, gridBagConstraints);

        jLabelStatusSQL.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        jLabelStatusSQL.setMinimumSize(new java.awt.Dimension(4, 18));
        jLabelStatusSQL.setPreferredSize(new java.awt.Dimension(4, 18));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 5;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        jPanel7.add(jLabelStatusSQL, gridBagConstraints);

        jPanelSQL.add(jPanel7, java.awt.BorderLayout.SOUTH);

        jPanel14.setLayout(new java.awt.GridBagLayout());

        jLabel1.setText("Query language");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        jPanel14.add(jLabel1, gridBagConstraints);

        jComboBoxQueryType.setEditable(true);
        jComboBoxQueryType.setMinimumSize(new java.awt.Dimension(200, 18));
        jComboBoxQueryType.setPreferredSize(new java.awt.Dimension(200, 22));
        jComboBoxQueryType.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jComboBoxQueryTypeActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 4, 4);
        jPanel14.add(jComboBoxQueryType, gridBagConstraints);

        jPanel16.setLayout(new java.awt.GridBagLayout());

        jButtonLoadQuery.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/folder_database.png")));
        jButtonLoadQuery.setText("Load query");
        jButtonLoadQuery.setMargin(new java.awt.Insets(2, 4, 2, 4));
        jButtonLoadQuery.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonLoadQueryActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.weightx = 1.0;
        jPanel16.add(jButtonLoadQuery, gridBagConstraints);

        jButtonSaveQuery.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/database_save.png")));
        jButtonSaveQuery.setText("Save query");
        jButtonSaveQuery.setMargin(new java.awt.Insets(2, 4, 2, 4));
        jButtonSaveQuery.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSaveQueryActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4);
        jPanel16.add(jButtonSaveQuery, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        jPanel14.add(jPanel16, gridBagConstraints);

        jPanelSQL.add(jPanel14, java.awt.BorderLayout.NORTH);

        jTabbedPane1.addTab("Report query ", jPanelSQL);

        jPanel5.setLayout(new java.awt.GridBagLayout());

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 3, 5, 3);
        jPanel5.add(jTextFieldBeanClass, gridBagConstraints);

        jLabel2.setText("Class name");
        jLabel2.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 5, 3);
        jPanel5.add(jLabel2, gridBagConstraints);

        jButtonReadBeanAttributes.setText("Read javabeans attributes");
        jButtonReadBeanAttributes.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonReadBeanAttributesActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 3, 5, 3);
        jPanel5.add(jButtonReadBeanAttributes, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.weighty = 1.0;
        jPanel5.add(jPanel10, gridBagConstraints);

        jTabbedPane1.addTab("JavaBean Datasource", jPanel5);

        jPanel8.setLayout(new java.awt.GridBagLayout());

        jPanel8.setMinimumSize(new java.awt.Dimension(235, 30));
        jPanel8.setPreferredSize(new java.awt.Dimension(215, 30));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 3, 5, 3);
        jPanel8.add(jTextFieldBeanClass1, gridBagConstraints);

        jLabel3.setText("Class name");
        jLabel3.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 5, 3);
        jPanel8.add(jLabel3, gridBagConstraints);

        jButtonReadBeanAttributes3.setText("Read attributes");
        jButtonReadBeanAttributes3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonReadBeanAttributes3ActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 3, 5, 3);
        jPanel8.add(jButtonReadBeanAttributes3, gridBagConstraints);

        jPanel11.setLayout(new java.awt.GridBagLayout());

        jTree1.setRootVisible(false);
        jTree1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTree1MouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jTree1MouseEntered(evt);
            }
        });

        jScrollPane1.setViewportView(jTree1);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanel11.add(jScrollPane1, gridBagConstraints);

        jPanel12.setLayout(new java.awt.GridBagLayout());

        jPanel12.setPreferredSize(new java.awt.Dimension(120, 50));
        jPanel12.setMinimumSize(new java.awt.Dimension(120, 50));
        jButton1.setText("Add field(s)");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4);
        jPanel12.add(jButton1, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanel12.add(jPanel13, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        jPanel11.add(jPanel12, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanel8.add(jPanel11, gridBagConstraints);

        jSeparator1.setPreferredSize(new java.awt.Dimension(0, 4));
        jSeparator1.setMinimumSize(new java.awt.Dimension(0, 4));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
        jPanel8.add(jSeparator1, gridBagConstraints);

        jTabbedPane1.addTab("JavaBean Ext Datasource", jPanel8);

        jButton2.setText("Get fields from datasource");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jPanel6.add(jButton2);

        jTabbedPane1.addTab("DataSource Provider", jPanel6);

        jButton3.setText("Get fields from datasource");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed1(evt);
            }
        });

        jPanel15.add(jButton3);

        jTabbedPane1.addTab("CSV Datasource", jPanel15);

        jPanel1.add(jTabbedPane1, java.awt.BorderLayout.CENTER);

        jSplitPane1.setTopComponent(jPanel1);

        jPanel2.setLayout(new java.awt.BorderLayout());

        jPanel2.setPreferredSize(new java.awt.Dimension(453, 150));
        columnsScrollPane.setPreferredSize(new java.awt.Dimension(453, 150));
        jTableFields.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Field name", "Field type", "Description"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false, false, false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jTableFields.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                jTableFieldsKeyReleased(evt);
            }
        });

        columnsScrollPane.setViewportView(jTableFields);

        jPanel2.add(columnsScrollPane, java.awt.BorderLayout.CENTER);

        jPanel3.setLayout(new java.awt.BorderLayout());

        jPanel3.setPreferredSize(new java.awt.Dimension(10, 34));
        jPanel3.setMinimumSize(new java.awt.Dimension(10, 34));
        jPanel4.setLayout(new java.awt.GridBagLayout());

        jPanel4.setPreferredSize(new java.awt.Dimension(150, 10));
        okButton.setText("OK");
        okButton.setEnabled(false);
        okButton.setMaximumSize(new java.awt.Dimension(67, 25));
        okButton.setMinimumSize(new java.awt.Dimension(67, 25));
        okButton.setPreferredSize(new java.awt.Dimension(67, 25));
        okButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okButtonActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        jPanel4.add(okButton, gridBagConstraints);

        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4);
        jPanel4.add(cancelButton, gridBagConstraints);

        jPanel3.add(jPanel4, java.awt.BorderLayout.EAST);

        jPanel9.setLayout(null);

        jPanel9.setMinimumSize(new java.awt.Dimension(100, 20));
        jPanel3.add(jPanel9, java.awt.BorderLayout.CENTER);

        jPanel2.add(jPanel3, java.awt.BorderLayout.SOUTH);

        columnsErrorMsgLabel.setText("jLabel1");
        columnsErrorMsgLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        columnsErrorMsgLabel.setVerticalTextPosition(javax.swing.SwingConstants.TOP);
        columnsErrorScrollPane.setViewportView(columnsErrorMsgLabel);

        jPanel2.add(columnsErrorScrollPane, java.awt.BorderLayout.CENTER);

        jSplitPane1.setBottomComponent(jPanel2);

        getContentPane().add(jSplitPane1, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonSaveQueryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSaveQueryActionPerformed

       Misc.saveSQLQuery( jRSQLExpressionArea1.getText(), this );
        
    }//GEN-LAST:event_jButtonSaveQueryActionPerformed

    private void jButtonLoadQueryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonLoadQueryActionPerformed

        
            String query = Misc.loadSQLQuery(this);
            
            if (query != null)
            {
                jRSQLExpressionArea1.setText(query);
            }
            
    }//GEN-LAST:event_jButtonLoadQueryActionPerformed

    private void jComboBoxQueryTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBoxQueryTypeActionPerformed
// TODO add your handling code here:
    }//GEN-LAST:event_jComboBoxQueryTypeActionPerformed

    private void jButton2ActionPerformed1(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed1
        IReportConnection conn = (IReportConnection)MainFrame.getMainInstance().getProperties().get("DefaultConnection");
        if (conn == null || !(conn instanceof it.businesslogic.ireport.connection.JRCSVDataSourceConnection)) {
            setColumnsError( "The active connection is not a JasperReports CSV DataSource." );
            return;
        }
        else
        {
            it.businesslogic.ireport.connection.JRCSVDataSourceConnection ic = (it.businesslogic.ireport.connection.JRCSVDataSourceConnection)conn;
            try {
                Vector names = ic.getColumnNames();
                DefaultTableModel dtm = (DefaultTableModel)jTableFields.getModel();
                dtm.setRowCount(0);
            
                for (int nd =0; nd < names.size(); ++nd) {
                    String fieldName = ""+names.elementAt(nd);
                    it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField(fieldName, "java.lang.String");
                    field.setDescription(""); //Field returned by " +methods[i].getName() + " (real type: "+ returnType +")");
                    
                    Vector row = new Vector();
                    row.addElement(field);
                    row.addElement(field.getClassType());
                    row.addElement(field.getDescription());
                    dtm.addRow(row);
                }
                jTableFields.setRowSelectionInterval(0, names.size()-1);
            } catch (Exception ex)
            {
                setColumnsError( "" + ex.getMessage() );
            
            }
        }
    }//GEN-LAST:event_jButton2ActionPerformed1

    private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened

    }//GEN-LAST:event_formWindowOpened

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
       
        IReportConnection conn = (IReportConnection)MainFrame.getMainInstance().getProperties().get("DefaultConnection");
        if (conn == null || !(conn instanceof it.businesslogic.ireport.connection.JRDataSourceProviderConnection)) {
            setColumnsError( "The active connection is not a JasperReports DataSource provider." );
            return;
        }
        else
        {
            it.businesslogic.ireport.connection.JRDataSourceProviderConnection ic = (it.businesslogic.ireport.connection.JRDataSourceProviderConnection)conn;
            try {
                Report rep = MainFrame.getMainInstance().getActiveReportFrame().getReport();
                
                net.sf.jasperreports.engine.design.JasperDesign report = new net.sf.jasperreports.engine.design.JasperDesign();
                JRDesignQuery queryDes = new JRDesignQuery();
                queryDes.setText(jRSQLExpressionArea1.getText());
                 String queryLanguage = "sql";
                 Object obj = jComboBoxQueryType.getSelectedItem();
                if (obj != null && obj instanceof Tag) 
                {
                    queryLanguage = ""+((Tag)obj).getValue();
                }
                else
                {
                    queryLanguage = ""+obj;
                }     
                queryDes.setLanguage( queryLanguage );
                report.setQuery( queryDes);
                
                for (int i=0; i< rep.getJRproperties().size(); ++i)
                {
                    JRProperty property = (JRProperty)rep.getJRproperties().elementAt(i);
                    report.setProperty(property.getName(), property.getValue());
                }
                
                for (int i=0; i< rep.getParameters().size(); ++i)
                {
                    JRParameter ireportParam = (JRParameter)rep.getParameters().elementAt(i);
                    if (ireportParam.isBuiltin()) continue;
                    net.sf.jasperreports.engine.design.JRDesignParameter  param = new net.sf.jasperreports.engine.design.JRDesignParameter();
                    param.setName(  ireportParam.getName() );
                    JRDesignExpression de = new JRDesignExpression();
                    de.setText( ireportParam.getDefaultValueExpression() );
                    de.setValueClassName( ireportParam.getClassType() );
                    param.setDefaultValueExpression( de );
                    param.setForPrompting(ireportParam.isIsForPrompting() );
                    param.setValueClassName(  ireportParam.getClassType() );
                    report.addParameter( param );
                }
                
                try {
                    
                    report.setName(rep.getName());
                } catch (Exception ex)
                {
                    
                }
                
                // Create a temporary JasperReports object...
                net.sf.jasperreports.engine.JasperReport jr = new net.sf.jasperreports.engine.JasperReport(report,"",null,null,"");
                
            net.sf.jasperreports.engine.JRField[] jrfields = ic.getDataSourceProvider().getFields( jr );
            DefaultTableModel dtm = (DefaultTableModel)jTableFields.getModel();
            dtm.setRowCount(0);
            for (int i=0; i< jrfields.length; ++i)
            {
                it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField(jrfields[i].getName(), jrfields[i].getValueClassName());
                field.setDescription( it.businesslogic.ireport.util.Misc.nvl( jrfields[i].getDescription(),""));
                Vector row = new Vector();
                row.addElement(field);
                row.addElement(field.getClassType());
                row.addElement(field.getDescription());
                dtm.addRow(row);
            }
            } catch (Exception ex)
            {
                setColumnsError( "" + ex.getMessage() );
            
            }
        }
        
    }//GEN-LAST:event_jButton2ActionPerformed

    private void exportQueryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportQueryButtonActionPerformed
       
        FieldReader fr = new FieldReader(jRSQLExpressionArea1.getText(), null);
        String query = fr.interpretQuery();
        
        java.awt.datatransfer.Clipboard clipboard = java.awt.Toolkit.getDefaultToolkit().getSystemClipboard();
        StringSelection fieldContent = new StringSelection (query);
        
     	clipboard.setContents (fieldContent, this);

        
        // TODO add your handling code here:
    }//GEN-LAST:event_exportQueryButtonActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        
        // Get all selected paths...
        if (MainFrame.getMainInstance().getActiveReportFrame() == null){
            return;
        }
        
        DefaultTableModel dtm = (DefaultTableModel)jTableFields.getModel();
         
        TreePath[] paths = jTree1.getSelectionPaths();
        
        for (int i=0; i<paths.length; ++i)
        {
            boolean valid = true;
            TreePath tp = paths[i];

            TreeJRField tjrf =  (TreeJRField)((DefaultMutableTreeNode)tp.getLastPathComponent()).getUserObject();
            String returnType =  Misc.getJRFieldType( tjrf.getObj().getName() );
            it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField(tjrf.getField().getName(), returnType);
            field.setDescription(tjrf.getField().getDescription() );
            Vector row = new Vector();
            row.addElement(field);
            row.addElement(field.getClassType());
            row.addElement(field.getDescription());
            
            // Check for duplicates fields...
            boolean found = false;
            for (int j=0; j<jTableFields.getRowCount(); ++j)
            {
               Object ff = jTableFields.getValueAt(j, 0);
               if ( ff instanceof it.businesslogic.ireport.JRField )
               {
                   if ( ((it.businesslogic.ireport.JRField)ff).getName().equals(field.getName()))
                   {
                       found = true;
                       break;
                   }
               }
            }
            if (!found)
            {
                dtm.addRow(row);
            }
        }
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jTree1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTree1MouseClicked
        if (evt.getClickCount() == 2 && evt.getButton() == evt.BUTTON1)
        {
            DefaultMutableTreeNode tn = (DefaultMutableTreeNode)jTree1.getSelectionPath().getLastPathComponent();
            
            if (tn.getChildCount()>0) return;
            
                /*if (!jTree1.isCollapsed( jTree1.getSelectionPath() ))
            {
                jTree1.collapsePath( jTree1.getSelectionPath() );
                return;
            }
                 *
                 */
            if (tn.getUserObject() instanceof TreeJRField)
            {
                TreeJRField jrf = (TreeJRField)tn.getUserObject();
                if (!jrf.getObj().isPrimitive() && !jrf.getObj().getName().startsWith("java.lang."))
                {
                   exploreBean(tn, jrf.getObj().getName(), Misc.nvl( jrf.getField().getDescription(), ""));
                }
            }
        }       
    }//GEN-LAST:event_jTree1MouseClicked

    private void jTree1MouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTree1MouseEntered
        
      
    }//GEN-LAST:event_jTree1MouseEntered

    private void jButtonReadBeanAttributes3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonReadBeanAttributes3ActionPerformed
        
        
        
        if (MainFrame.getMainInstance().getActiveReportFrame() == null){
            return;
        }
        
        DefaultTableModel dtm = (DefaultTableModel)jTableFields.getModel();
        dtm.setRowCount(0);
        jTableFields.updateUI();
        
         DefaultTreeModel dttm = (DefaultTreeModel)jTree1.getModel();
         DefaultMutableTreeNode root = new DefaultMutableTreeNode();
         jTree1.setModel(new DefaultTreeModel( root ));
            
         String classname = jTextFieldBeanClass1.getText().trim();
         if (classname.equals("")){
         
            javax.swing.JOptionPane.showMessageDialog(this, "No class specified!","Error",javax.swing.JOptionPane.ERROR_MESSAGE);
            return;
        }
        
          exploreBean(root, classname, "");
         
    }//GEN-LAST:event_jButtonReadBeanAttributes3ActionPerformed

    protected void getFieldsFromClass(Class clazz, String path) throws Exception
    {
         DefaultTableModel dtm = (DefaultTableModel)jTableFields.getModel();
            
         java.lang.reflect.Method[] methods = clazz.getMethods();
         java.lang.reflect.Field[] fields = clazz.getFields();
         // for any method, looking for get<FieldName> ....
            
            
         for (int i=0; i<methods.length; ++i)
         {
               
                if ( java.lang.reflect.Modifier.isPublic( methods[i].getModifiers() ) &&
                     methods[i].getDeclaringClass().getName().equals(clazz.getName() ) &&
                     !java.lang.reflect.Modifier.isNative( methods[i].getModifiers() )     
                     && methods[i].getName().startsWith("get")
                        && !methods[i].getReturnType().isPrimitive() 
                        && !methods[i].getReturnType().isArray())
                {
                   String fieldName = methods[i].getName().substring(3);
                   // Looking for the field...
                   for (int f=0; f<fields.length; ++f)
                   {
                       if (fields[f].getName().equalsIgnoreCase( fieldName ))
                       {
                           
                           fieldName = fields[f].getName();
                           break;
                       }
                   }
                   
                   String returnType =  methods[i].getReturnType().getName();
                   boolean found = false;
                   for (int cc=0; cc<standard_types.length; ++cc)
                   {
                        if ( returnType.equalsIgnoreCase(standard_types[cc]))
                        {                       
                            it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField(fieldName, returnType);
                            field.setDescription(path + "" + fieldName);
                            Vector row = new Vector();
                            row.addElement(field);
                            row.addElement(field.getClassType());
                            row.addElement(field.getDescription());
                            dtm.addRow(row);
                            found = true;
                            break;
                        }
                  }
                  if (!found)
                  {
                        it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField(fieldName, "java.lang.Object");
                        field.setDescription(path + "" + fieldName);
                        Vector row = new Vector();
                        row.addElement(field);
                        row.addElement(field.getClassType());
                        row.addElement(field.getDescription());
                        dtm.addRow(row);
                        Class subClazz = Class.forName(returnType);
                        getFieldsFromClass( subClazz , path + fieldName + ".");
                  }
                }
            }                    
    }
    



    private void automaticlyReadFieldsCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_automaticlyReadFieldsCheckBoxActionPerformed
        if( automaticlyReadFieldsCheckBox.isSelected() ) {
            // Automagically get quiery fields.
            // User has just enabled this so get field list.
            readFieldsButton.setEnabled(false);
            processQueryChanged( jRSQLExpressionArea1.getText().trim() );
        } else {
            // Turn off automagic field reading. User will have to press the 
            // Read Fields button
            //okButton.setEnabled(false);
            readFieldsButton.setEnabled(true);
            //setColumnsError( "Enter your query above. Then use the Read " +
            //        "Fields button to retrieve the list of fields." );
            this.jLabelStatusSQL.setText("Enter your query above. Then use the Read " +
                    "Fields button to retrieve the list of fields." );
        }
        
    }//GEN-LAST:event_automaticlyReadFieldsCheckBoxActionPerformed

    private void readFieldsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_readFieldsButtonActionPerformed
        processQueryChanged( jRSQLExpressionArea1.getText().trim() );
    }//GEN-LAST:event_readFieldsButtonActionPerformed

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        // No changes.
        num++;
        this.setVisible(false);
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
        
        try {
        if (stoppedChanging != null) stoppedChanging.stop();
  
        if ( this.getSubDataset() != null)
        {       
            num++; // avoid syncronization problems....
            
            Object obj = jComboBoxQueryType.getSelectedItem();
            if (obj != null && obj instanceof Tag) 
            {
                this.subDataset.setQueryLanguage(""+((Tag)obj).getValue());
            }
            else
            {
                this.subDataset.setQueryLanguage(""+obj);
            }
            // save the query to the report.
            this.subDataset.setQuery( jRSQLExpressionArea1.getText());                
            
            if ( jTableFields.getRowCount() > 0)
            {
                // Clear all the existing fields.
                this.subDataset.getFields().clear();
    
                // Add the new fields.
                int[] selectedRows = jTableFields.getSelectedRows();
                for (int i=0; i<selectedRows.length  ; ++i) {
                    if (selectedRows[i] > jTableFields.getRowCount()) continue;

                    it.businesslogic.ireport.JRField field = (it.businesslogic.ireport.JRField)this.jTableFields.getValueAt(selectedRows[i], 0);
                    Enumeration e = this.subDataset.getFields().elements();
                    boolean found = false;
                    while (e.hasMoreElements()) {
                        it.businesslogic.ireport.JRField f = (it.businesslogic.ireport.JRField)e.nextElement();
                        if (f.getName().equalsIgnoreCase(field.getName())) {
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        this.subDataset.addField(field);
                    }
                }
                if (subDataset instanceof Report)
                {
                    MainFrame.getMainInstance().getValuesDialog().getValuesPanel().updateFields();
                }
            } 
       }
       
       } catch (Throwable ex)
            {
                ex.printStackTrace();
            }
       
       this.setVisible(false);
        
    }//GEN-LAST:event_okButtonActionPerformed

    private void jTableFieldsKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTableFieldsKeyReleased
        
        //javax.swing.JOptionPane.showMessageDialog(null,"Key: "+evt.getKeyCode() + " (" + java.awt.event.KeyEvent.VK_DELETE + ")");
        if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_DELETE)
        {
             javax.swing.table.DefaultTableModel dtm =  (javax.swing.table.DefaultTableModel)jTableFields.getModel();
             int[] selectedRows = jTableFields.getSelectedRows();
             for (int i= selectedRows.length-1; i>=0; --i) 
             {
                 it.businesslogic.ireport.JRField field = (it.businesslogic.ireport.JRField)this.jTableFields.getValueAt( i, 0);
                 this.subDataset.removeField(field);
                 this.jTableFields.removeRowSelectionInterval(i,i);
             }
        }
    }//GEN-LAST:event_jTableFieldsKeyReleased

    private void jButtonReadBeanAttributesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonReadBeanAttributesActionPerformed
        String classname = jTextFieldBeanClass.getText().trim();
        if (classname.equals("")){
         
            javax.swing.JOptionPane.showMessageDialog(this, "No class specified!","Error",javax.swing.JOptionPane.ERROR_MESSAGE);
            return;
        }
        try {
            
            DefaultTableModel dtm = (DefaultTableModel)jTableFields.getModel();
            dtm.setRowCount(0);
            
            ReportClassLoader reportClassLoader = new ReportClassLoader();
            reportClassLoader.rescanLibDirectory();
            Class clazz = Class.forName(classname,true,reportClassLoader); 

            java.beans.PropertyDescriptor[] pd = org.apache.commons.beanutils.PropertyUtils.getPropertyDescriptors(clazz);
            for (int nd =0; nd < pd.length; ++nd)
            {
                   String fieldName = pd[nd].getName();
                   if (pd[nd].getPropertyType() != null && pd[nd].getReadMethod() != null)
                   {
                       String returnType =  pd[nd].getPropertyType().getName();
                       it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField(fieldName, Misc.getJRFieldType(returnType));
                       field.setDescription(""); //Field returned by " +methods[i].getName() + " (real type: "+ returnType +")");
                       Vector row = new Vector();
                       row.addElement(field);
                       row.addElement(field.getClassType());
                       row.addElement(field.getDescription());
                       dtm.addRow(row);
                   }
            }
            jTableFields.setRowSelectionInterval(0, jTableFields.getRowCount()-1);
            
            /*
            java.lang.reflect.Method[] methods = Class.forName(classname).getMethods();
            java.lang.reflect.Field[] fields = Class.forName(classname).getFields();
            
            // for any method, looking for get<FieldName> ....
            
            DefaultTableModel dtm = (DefaultTableModel)jTableFields.getModel();
            dtm.setRowCount(0);
            
            for (int i=0; i<methods.length; ++i)
            {
               // methods[i].getDeclaringClass().getName().equals(classname) &&
                if ( java.lang.reflect.Modifier.isPublic( methods[i].getModifiers() ) &&
                      
                     !java.lang.reflect.Modifier.isNative( methods[i].getModifiers() )     
                     && methods[i].getName().startsWith("get"))
                        //&& !methods[i].getReturnType().isPrimitive() 
                        //&& !methods[i].getReturnType().isArray()
                {
                   String fieldName = methods[i].getName().substring(3);
                   if (fieldName.length() > 0)
                   {
                       fieldName = fieldName.substring(0,1).toLowerCase() + fieldName.substring(1);
                   }
                   else continue;
                   
                   // Looking for the field...
                   for (int f=0; f<fields.length; ++f)
                   {
                       if (fields[f].getName().equalsIgnoreCase( fieldName ))
                       {
                           
                           fieldName = fields[f].getName();
                           break;
                       }
                   }
                   
                   String returnType =  methods[i].getReturnType().getName();
                   it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField(fieldName, getJRFieldType(returnType));
                   field.setDescription("Field returned by " +methods[i].getName() + " (real type: "+ returnType +")");
                   Vector row = new Vector();
                   row.addElement(field);
                   row.addElement(field.getClassType());
                   row.addElement(field.getDescription());
                   dtm.addRow(row);
                }
            }
             */
            
        } catch (ClassNotFoundException cnf)
        {
            javax.swing.JOptionPane.showMessageDialog(this, "Class not found!\nCheck your classpath and retry.","Error",javax.swing.JOptionPane.ERROR_MESSAGE);
            return;
        } catch (Exception ex)
        {
            ex.printStackTrace();
            javax.swing.JOptionPane.showMessageDialog(this, ex.getMessage() ,"Error",javax.swing.JOptionPane.ERROR_MESSAGE);
            return;
        }
    }//GEN-LAST:event_jButtonReadBeanAttributesActionPerformed
    
    
    
    
    
    /** Closes the dialog */
    private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
        setVisible(false);
        dispose();
    }//GEN-LAST:event_closeDialog
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        new ReportQueryDialog(new javax.swing.JFrame(), true).setVisible(true);
    }
        
    Map parameterNameToExpressionID = null;
    
    /**
     * Create an expression evaluator for report parameters.
     *
     */
    private Interpreter prepareExpressionEvaluator() throws bsh.EvalError {
        
        /*
        JasperDesign jd = new JasperDesign();

        parameterNameToExpressionID = new HashMap();
        
        Enumeration enumParams = subDataset.getParameters().elements();
        while( enumParams.hasMoreElements() ) {
            it.businesslogic.ireport.JRParameter parameter = (it.businesslogic.ireport.JRParameter)enumParams.nextElement();

            if( parameter.getDefaultValueExpression().length()==0 ) {
                // no default value for this param
                continue;
            }
            
            Class c = classStringToClass( parameter.getClassType() );
            
            JRDesignParameter p = new JRDesignParameter();
            //JRDesignExpression exp = parameter.getDefaultValueExpression();
            JRDesignExpression exp = new JRDesignExpression();
            if (c==null) c = java.lang.Object.class;
            exp.setValueClass( c );
            //exp.setName("parameterDefaultValue_" + parameter.getName() );
            exp.setText( parameter.getDefaultValueExpression() );
            p.setName( parameter.getName() );
            p.setValueClass( c );
            p.setForPrompting( false );
            p.setDefaultValueExpression( exp );
            jd.addParameter( p );
            parameterNameToExpressionID.put( parameter.getName(), new Integer(exp.getId()) );
        }

        
        String bshScript = JRBshGenerator.generateScript( jd );
        */
        Interpreter interpreter = new Interpreter();
        interpreter.setClassLoader(interpreter.getClass().getClassLoader());
        
        // Staring patch from rp4
        StringTokenizer  st = new StringTokenizer( MainFrame.getMainInstance().getProperties().getProperty("classpath",""),"\n");
        interpreter.eval("String tmp;");
        while (st.hasMoreTokens())
        {
            String token = st.nextToken();
            if (token != null && token.trim().length() > 0)
            {
                interpreter.set("tmp", token.trim());
                interpreter.eval("addClassPath(tmp);");
            }
        }        
       
        // Add report import directives to the bsh interpreter
        Enumeration imps = MainFrame.getMainInstance().getActiveReportFrame().getReport().getImports().elements();
        while ( imps.hasMoreElements() )
        {
            String var = (String)imps.nextElement();
            interpreter.eval("import " + var + ";");
        }
        // End patch from rp4
        /*
        interpreter.eval(new StringReader(bshScript));

        interpreter.eval("bshCalculator = createBshCalculator()");
        */
        return interpreter;
         
        // return null;
    }

    /**
     * Convert a class name string into its class object.
     * There must be a function in JasperReports that does this somewhere.
     *
     *
     */
    private Class classStringToClass(String classType) {
        Class c = null;
        
        
        if ( classType.equals("java.lang.String") ) {
            c = java.lang.String.class;
        } else if ( classType.equals("java.lang.Integer") ) {
            c = java.lang.Integer.class;
        } else if ( classType.equals("java.lang.Boolean") ) {
            c = java.lang.Boolean.class;
        } else if ( classType.equals("java.lang.Byte") ) {
            c = java.lang.Byte.class;
        } else if ( classType.equals("java.util.Date") ) {
            c = java.util.Date.class;
        } else if ( classType.equals("java.sql.Timestamp") ) {
            c = java.sql.Timestamp.class;
        } else if ( classType.equals("java.sql.Time") ) {
            c = java.sql.Time.class;
        } else if ( classType.equals("java.lang.Double") ) {
            c = java.lang.Double.class;
        } else if ( classType.equals("java.lang.Float") ) {
            c = java.lang.Float.class;
        } else if ( classType.equals("java.lang.Long") ) {
            c = java.lang.Long.class;
        } else if ( classType.equals("java.lang.Short") ) {
            c = java.lang.Short.class;
        } else if ( classType.equals("java.math.BigDecimal") ) {
            c = java.math.BigDecimal.class;
        }
        
        return c;
    }
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox automaticlyReadFieldsCheckBox;
    private javax.swing.JButton cancelButton;
    private javax.swing.JLabel columnsErrorMsgLabel;
    private javax.swing.JScrollPane columnsErrorScrollPane;
    private javax.swing.JScrollPane columnsScrollPane;
    private javax.swing.JButton exportQueryButton;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButtonLoadQuery;
    private javax.swing.JButton jButtonReadBeanAttributes;
    private javax.swing.JButton jButtonReadBeanAttributes3;
    private javax.swing.JButton jButtonSaveQuery;
    private javax.swing.JComboBox jComboBoxQueryType;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabelStatusSQL;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel10;
    private javax.swing.JPanel jPanel11;
    private javax.swing.JPanel jPanel12;
    private javax.swing.JPanel jPanel13;
    private javax.swing.JPanel jPanel14;
    private javax.swing.JPanel jPanel15;
    private javax.swing.JPanel jPanel16;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JPanel jPanel8;
    private javax.swing.JPanel jPanel9;
    private javax.swing.JPanel jPanelSQL;
    private it.businesslogic.ireport.gui.JRSQLExpressionArea jRSQLExpressionArea1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JTable jTableFields;
    private javax.swing.JTextField jTextFieldBeanClass;
    private javax.swing.JTextField jTextFieldBeanClass1;
    private javax.swing.JTree jTree1;
    private javax.swing.JButton okButton;
    private javax.swing.JButton readFieldsButton;
    // End of variables declaration//GEN-END:variables
    
    private boolean isSettingSQLExpression = false;
    
    
    public void exploreBean(DefaultMutableTreeNode root, String classname, String parentPath)
    {
        try {
            
            root.removeAllChildren();
            if (parentPath.length() > 0) parentPath += ".";
            
            ReportClassLoader reportClassLoader = new ReportClassLoader();
            reportClassLoader.rescanLibDirectory();
            Class clazz = Class.forName(classname,true,reportClassLoader);
            
            java.beans.PropertyDescriptor[] pd = org.apache.commons.beanutils.PropertyUtils.getPropertyDescriptors(clazz);
            for (int nd =0; nd < pd.length; ++nd)
            {
                   String fieldName = pd[nd].getName();
                   if (pd[nd].getPropertyType() != null && pd[nd].getReadMethod() != null)
                   {
                       String returnType =  pd[nd].getPropertyType().getName();
                       it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField( Misc.getJRFieldType( fieldName ), returnType);
                       field.setDescription(parentPath + fieldName);
                       TreeJRField jtf = new TreeJRField();
                   
                       jtf.setField( field );
                       jtf.setObj( pd[nd].getPropertyType() );
                   
                       boolean bChildrens = true;
                       if (pd[nd].getPropertyType().isPrimitive() || pd[nd].getPropertyType().getName().startsWith("java.lang."))
                       {
                           bChildrens = false;
                       }
                       root.add(new DefaultMutableTreeNode(jtf, bChildrens));
                   }
            }
            
            
            /**
            java.lang.reflect.Method[] methods = clazz.getMethods();
            java.lang.reflect.Field[] fields = clazz.getFields();
            // for any method, looking for get<FieldName> ....

            for (int i=0; i<methods.length; ++i)
            {
               //System.out.println( methods[i].getName());
                if ( java.lang.reflect.Modifier.isPublic( methods[i].getModifiers() ) &&
                     methods[i].getDeclaringClass().getName().equals(classname) &&
                     !java.lang.reflect.Modifier.isNative( methods[i].getModifiers() )     
                     && methods[i].getName().startsWith("get")
                        && !methods[i].getReturnType().isPrimitive() 
                        && !methods[i].getReturnType().isArray())
                {
                   String fieldName = methods[i].getName().substring(3);
                   
                   if (fieldName.length() == 0) continue;
                   // Looking for the field...
                   for (int f=0; f<fields.length; ++f)
                   {
                       if (fields[f].getName().equalsIgnoreCase( fieldName ))
                       {
                           fieldName = fields[f].getName();
                           break;
                       }
                   }
                   
                   
                   String returnType =  methods[i].getReturnType().getName();
                   it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField(fieldName, returnType);
                   field.setDescription(parentPath + fieldName);
                   TreeJRField jtf = new TreeJRField();
                   
                   jtf.setField( field );
                   jtf.setObj( methods[i].getReturnType() );
                   
                   boolean bChildrens = true;
                   if (methods[i].getReturnType().getName().startsWith("java.lang."))
                   {
                       bChildrens = false;
                   }
                   root.add(new DefaultMutableTreeNode(jtf, bChildrens));
                }
            }
             **/
            
            jTree1.expandPath( new TreePath(root.getPath()) );
            jTree1.updateUI();
            
        } catch (ClassNotFoundException cnf)
        {
            javax.swing.JOptionPane.showMessageDialog(this, "Class not found!\nCheck your classpath and retry.\n" + cnf.getMessage(),"Error",javax.swing.JOptionPane.ERROR_MESSAGE);
            return;
        } catch (Exception ex)
        {
            javax.swing.JOptionPane.showMessageDialog(this, ex.getMessage() ,"Error",javax.swing.JOptionPane.ERROR_MESSAGE);
            return;
        }
    }
    
    public void lostOwnership (Clipboard parClipboard, Transferable parTransferable) { }

    public static Object recursiveInterpreter(Interpreter interpreter, String expression, Vector parameters) throws EvalError
    {
        return recursiveInterpreter(interpreter, expression, parameters, 0);
    }
    
    public static  Object recursiveInterpreter(Interpreter interpreter, String expression, Vector parameters, int recursion_level) throws EvalError
    {
        ++recursion_level;
        //System.out.println("Valuto ["+ recursion_level +"]: " + expression);
        if (recursion_level > 100) return null;
        if (expression != null && expression.trim().length() > 0)
        {
            // for each parameter, we have to calc the real value...
            while (expression.indexOf("$P{") >= 0)
            {
                int start_index = expression.indexOf("$P{")+3;
                String param_name = expression.substring(start_index, expression.indexOf("}", start_index) );
                String param_expression = "";
                for (int i=0; i<parameters.size(); ++i)
                {
                    JRParameter p = (JRParameter)parameters.elementAt(i);
                    if (p.getName().equals( param_name))
                    {
                        param_expression = p.getDefaultValueExpression();
                        break;
                    }
                }
                
                expression = Misc.string_replace( param_name, "$P{"+param_name+"}", expression);
                interpreter.set( param_name, recursiveInterpreter(interpreter, param_expression, parameters, recursion_level));
            }
            
            //System.out.println("interpreto ["+ recursion_level +"]: " + expression);
            Object res = interpreter.eval(expression);
            //System.out.println("Result: " + res);
            return res;
        }
        return null;
    }

    private SubDataset subDataset;

    public SubDataset getSubDataset() {
        return subDataset;
    }

    public void setSubDataset(SubDataset subDataset) {
        this.subDataset = subDataset;
        
        DefaultTableModel dtm = (DefaultTableModel)jTableFields.getModel();
        dtm.setRowCount(0); 
        
        num++;
        jLabelStatusSQL.setText( "" );
        
        // Load query...
        if (subDataset == null)
            this.jRSQLExpressionArea1.setText("");
        else
        {
            // Use query, and use existing field list. ie Dont load from DB
            isSettingSQLExpression = true;
            this.jRSQLExpressionArea1.setText( this.subDataset.getQuery() );
            isSettingSQLExpression = false;
            
            List columns = new ArrayList();
            Iterator i = subDataset.getFields().iterator();
            while( i.hasNext() ) {
                it.businesslogic.ireport.JRField field = (it.businesslogic.ireport.JRField)i.next();
                columns.add( new Object[]{field, field.getClassType()} );
            }
            setColumns( columns );
            
            for (int ix=3; ix<jComboBoxQueryType.getItemCount(); ++ix)
            {
               jComboBoxQueryType.removeItemAt(ix);
            }

            boolean found = false;
            for (int ix=0; ix<jComboBoxQueryType.getItemCount(); ++ix)
            {
               Tag t = (Tag)jComboBoxQueryType.getItemAt(ix);
               if (t.getValue().equals(subDataset.getQueryLanguage()))
               {
                   found = true;
                   jComboBoxQueryType.setSelectedIndex(ix);
                   break;
               }
            }
            if (!found) // Default is sql...
            {
                jComboBoxQueryType.setEditable(true);
                jComboBoxQueryType.setSelectedItem(subDataset.getQueryLanguage());
            }
        }
    }
}


