001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2002-2005 Julian Hyde
008// Copyright (C) 2005-2011 Pentaho and others
009// Copyright (C) 2006-2007 Cincom Systems, Inc.
010// All Rights Reserved.
011*/
012package mondrian.gui;
013
014import mondrian.gui.validate.ValidationUtils;
015import mondrian.olap.*;
016import mondrian.olap.Util.PropertyList;
017
018import org.apache.log4j.Logger;
019
020import java.awt.*;
021import java.awt.event.*;
022import java.io.*;
023import java.util.*;
024import java.util.List;
025import javax.swing.*;
026import javax.swing.text.DefaultEditorKit;
027
028/**
029 * @author sean
030 */
031public class QueryPanel extends javax.swing.JPanel {
032
033    private static final Logger LOGGER = Logger.getLogger(QueryPanel.class);
034
035    Connection connection;
036    JMenuItem queryMenuItem;
037    int windowMenuIndex;
038
039    // map of schema frames and schema menu items
040    Map<JInternalFrame, JMenuItem> schemaWindowMap;
041
042    final Workbench workbench;
043
044    /**
045     * Creates new form QueryPanel
046     */
047    public QueryPanel(Workbench workbench) {
048        this.workbench = workbench;
049        initComponents();
050    }
051
052    public void setConnection(Connection c) {
053        connection = c;
054    }
055
056    public Connection getConnection() {
057        return connection;
058    }
059
060    //====================================================
061
062    public void setMenuItem(JMenuItem mi) {
063        this.queryMenuItem = mi;
064    }
065
066    public void setSchemaWindowMap(
067        Map<JInternalFrame, JMenuItem> schemaWindowMap)
068    {
069        this.schemaWindowMap = schemaWindowMap;
070        setCatalogs();
071    }
072
073    private void setCatalogs() {
074        List<String> v = new ArrayList<String>();
075        Iterator<JMenuItem> it = schemaWindowMap.values().iterator();
076        while (it.hasNext()) {
077            JMenuItem elem = it.next();
078            v.add(elem.getText());
079        }
080        ComboBoxModel cCatalogs =
081            new DefaultComboBoxModel(new Vector<String>(v));
082        schemaList.setModel(cCatalogs);
083    }
084
085    public void setWindowMenuIndex(int i) {
086        this.windowMenuIndex = i;
087    }
088
089    /**
090     * @return the workbench i18n converter
091     */
092    public I18n getResourceConverter() {
093        return workbench.getResourceConverter();
094    }
095
096    public void initConnection(String smenutext) {
097        schemaList.setSelectedItem(smenutext);
098        connectButtonActionPerformed(null);
099    }
100    //=====================================================
101
102    /**
103     * This method is called from within the constructor to
104     * initialize the form.
105     * WARNING: Do NOT modify this code. The content of this method is
106     * always regenerated by the Form Editor.
107     */
108    private void initComponents() {
109        jScrollPane3 = new javax.swing.JScrollPane();
110        executeButton = new javax.swing.JButton();
111        jSplitPane1 = new javax.swing.JSplitPane();
112        jScrollPane1 = new javax.swing.JScrollPane();
113        queryTextPane = new javax.swing.JTextPane();
114        jScrollPane2 = new javax.swing.JScrollPane();
115        resultTextPane = new javax.swing.JTextPane();
116        connectButton = new javax.swing.JButton();
117        jPopupMenu = new JPopupMenu();
118        jPopupMenu.add(new DefaultEditorKit.CutAction());
119        jPopupMenu.add(new DefaultEditorKit.CopyAction());
120        jPopupMenu.add(new DefaultEditorKit.PasteAction());
121
122        schemaScrollPane1 = new javax.swing.JScrollPane();
123        schemaLabel = new javax.swing.JLabel();
124        schemaList = new JComboBox(
125            new String[]{
126                getResourceConverter().getString(
127                    "common.join.title", "Join"),
128                getResourceConverter().getString(
129                    "common.table.title", "Table")
130            });
131        //schemaScrollPane1.setViewportView(schemaList);
132        schemaPanel = new JPanel();
133        //schemaPanel.setLayout(new BorderLayout(25,0));
134        schemaPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0));
135
136        setLayout(new java.awt.BorderLayout());
137
138        schemaLabel.setFont(new Font("Dialog", 1, 12));
139        schemaLabel.setForeground(
140            (Color) UIManager.getDefaults().get(
141                "CheckBoxMenuItem.acceleratorForeground"));
142        schemaLabel.setHorizontalAlignment(SwingConstants.CENTER);
143        schemaLabel.setText(
144            getResourceConverter().getString(
145                "common.schema.title", "Schema"));
146        //schemaLabel.setBorder(new EtchedBorder());
147
148        schemaList.setBackground(Color.white);
149        final JPanel qpanel = this;
150        schemaList.addItemListener(
151            new ItemListener() {
152                public void itemStateChanged(ItemEvent e) {
153                }
154            });
155        connectButton.setText(
156            getResourceConverter().getString(
157                "queryPanel.connect.title", "Connect"));
158        connectButton.addActionListener(
159            new ActionListener() {
160                public void actionPerformed(ActionEvent evt) {
161                    connectButtonActionPerformed(evt);
162                }
163            });
164
165        schemaPanel.add(schemaLabel); //java.awt.BorderLayout.WEST
166        schemaPanel.add(schemaList);
167        schemaPanel.add(connectButton);
168
169        add(schemaPanel, java.awt.BorderLayout.NORTH);
170
171        executeButton.setText(
172            getResourceConverter().getString(
173                "queryPanel.execute.title", "Execute"));
174        executeButton.addActionListener(
175            new ActionListener() {
176                public void actionPerformed(ActionEvent evt) {
177                    executeButtonActionPerformed(evt);
178                }
179            });
180
181        add(executeButton, java.awt.BorderLayout.SOUTH);
182
183        jSplitPane1.setDividerLocation(100);
184        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
185        queryTextPane.setFont(new java.awt.Font("Courier New", 0, 12));
186        queryTextPane.setText("");
187        queryTextPane.addMouseListener(
188            new MouseAdapter() {
189                // From MouseAdapter javadoc:
190                //
191                // Popup menus are triggered differently
192                // on different systems. Therefore, isPopupTrigger
193                // should be checked in both mousePressed
194                // and mouseReleased
195                // for proper cross-platform functionality.
196
197                public void mousePressed(MouseEvent e) {
198                    checkPopupTrigger(e);
199                }
200
201                public void mouseReleased(MouseEvent e) {
202                    checkPopupTrigger(e);
203                }
204
205                public void checkPopupTrigger(MouseEvent e) {
206                    if (e.isPopupTrigger()) {
207                        int x = e.getX();
208                        int y = e.getY();
209
210                        jPopupMenu.show(queryTextPane, x, y);
211                    }
212                }
213            });
214
215        jScrollPane1.setViewportView(queryTextPane);
216
217        jSplitPane1.setTopComponent(jScrollPane1);
218
219        resultTextPane.setEditable(false);
220        resultTextPane.setFont(new java.awt.Font("Courier New", 0, 12));
221        jScrollPane2.setViewportView(resultTextPane);
222
223        jSplitPane1.setBottomComponent(jScrollPane2);
224
225        add(jSplitPane1, java.awt.BorderLayout.CENTER);
226    }
227
228    private void executeButtonActionPerformed(ActionEvent evt) {
229        //run the query, and show the results.
230        try {
231            if (connection == null) {
232                JOptionPane.showMessageDialog(
233                    this, getResourceConverter().getString(
234                        "queryPanel.noConnection.alert",
235                        "No Mondrian connection. Select a Schema to connect."),
236                    getResourceConverter().getString(
237                        "common.alertDialog.title", "Alert"),
238                    JOptionPane.WARNING_MESSAGE);
239                return;
240            } //common.alertDialog.title
241            Query q = connection.parseQuery(queryTextPane.getText());
242
243            Result r = connection.execute(q);
244
245            //document = DomBuilder.build(getResult());
246            java.io.StringWriter sw = new java.io.StringWriter();
247            java.io.PrintWriter pw = new java.io.PrintWriter(sw);
248
249            r.print(pw);
250
251            resultTextPane.setText(sw.getBuffer().toString());
252        } catch (Exception ex) {
253            ByteArrayOutputStream os = new ByteArrayOutputStream();
254
255            PrintStream p = new PrintStream(os);
256
257            Throwable e = ex;
258            while (e != null) {
259                p.println(e.getLocalizedMessage());
260                LOGGER.error("", e);
261                Throwable prev = e;
262                e = e.getCause();
263                if (e == prev) {
264                    break;
265                }
266                p.println();
267            }
268
269            resultTextPane.setText(os.toString());
270        }
271    }
272
273    private void connectButtonActionPerformed(ActionEvent evt) {
274        File sfile = null;
275        try {
276            String sfname = (String) schemaList.getSelectedItem();
277            JInternalFrame sf = lookupFrame(sfname);
278
279            if (sf == null) {
280                // this case may arise when a schema file is opened, mdx query
281                // is opened and the schema frame is closed
282                JOptionPane.showMessageDialog(
283                    this, getResourceConverter().getString(
284                        "queryPanel.schemaNotOpen.alert",
285                        "Schema file is not open"),
286                    getResourceConverter().getString(
287                        "common.errorDialog.title", "Error"),
288                    JOptionPane.ERROR_MESSAGE);
289                return;
290            }
291
292            SchemaExplorer se =
293                (SchemaExplorer) sf.getContentPane().getComponent(0);
294            if (se.isNewFile()) {
295                JOptionPane.showMessageDialog(
296                    this,
297                    getResourceConverter().getString(
298                        "queryPanel.saveSchemaFirst.alert",
299                        "You must first save the Schema to open a Mondrian connection"),
300                    getResourceConverter().getString(
301                        "common.alertDialog.title", "Alert"),
302                    JOptionPane.WARNING_MESSAGE);
303                sf.setSelected(true);
304                return;
305            }
306            sfile = se.getSchemaFile();
307            PropertyList list = new PropertyList();
308            list.put("Provider", "mondrian");
309            list.put("Jdbc", se.getJdbcConnectionUrl());
310            list.put("Catalog", se.getSchemaFile().toURL().toString());
311            final String jdbcUsername = se.getJdbcUsername();
312            if (!ValidationUtils.isEmpty(jdbcUsername)) {
313                list.put("JdbcUser", jdbcUsername);
314            }
315            final String jdbcPassword = se.getJdbcPassword();
316            if (!ValidationUtils.isEmpty(jdbcPassword)) {
317                list.put("JdbcPassword", jdbcPassword);
318            }
319            Connection con = DriverManager.getConnection(list, null);
320
321            // clear cache before connecting
322            con.getCacheControl(null).flushSchemaCache();
323
324            if (con != null) {
325                connection = con;
326                queryMenuItem.setText(
327                    getResourceConverter().getFormattedString(
328                        "queryPanel.successfulConnection.menuItem",
329                        "{0} MDX - {1}",
330                        Integer.toString(windowMenuIndex),
331                        se.getSchemaFile().getName()));
332                Component o = this;
333                while (o != null) {
334                    if (o.getClass() == JInternalFrame.class) {
335                        ((JInternalFrame) o).setTitle(
336                            getResourceConverter().getFormattedString(
337                                "queryPanel.successfulConnection.internalFrame.title",
338                                "MDX Query - connected to {0}",
339                                se.getSchemaFile().getName()));
340                        break;
341                    }
342                    o = o.getParent();
343                }
344                JOptionPane.showMessageDialog(
345                    this,
346                    "Mondrian connection Successful.",
347                    getResourceConverter().getString(
348                        "common.informationDialog.title", "Information"),
349                    JOptionPane.INFORMATION_MESSAGE);
350            } else {
351                JOptionPane.showMessageDialog(
352                    this,
353                    getResourceConverter().getFormattedString(
354                        "queryPanel.unsuccessfulConnection.alert",
355                        "Mondrian connection could not be done for - {0}",
356                        se.getSchemaFile().getName()),
357                    getResourceConverter().getString(
358                        "common.errorDialog.title", "Error"),
359                    JOptionPane.ERROR_MESSAGE);
360            }
361        } catch (Exception ex) {
362            LOGGER.error("Exception: " + ex.getMessage(), ex);
363            JOptionPane.showMessageDialog(
364                this,
365                getResourceConverter().getFormattedString(
366                    "queryPanel.unsuccessfulConnection.exception",
367                    "Mondrian connection could not be done for - {0}",
368                    sfile == null
369                        ? getResourceConverter().getString(
370                            "queryPanel.selectedSchema.alert",
371                            "selected Schema")
372                        : sfile.getName()),
373                getResourceConverter().getString(
374                    "common.errorDialog.title", "Error"),
375                JOptionPane.ERROR_MESSAGE);
376            resultTextPane.setText(getResourceConverter().getFormattedString(
377                "queryPanel.exceptionMessage",
378                "Exception: {0}\n\nSee workbench log for full stacktrace.",
379                ex.getMessage()));
380        }
381    }
382
383    private JInternalFrame lookupFrame(String sfname) {
384        JInternalFrame sf = null;
385        for (Map.Entry<JInternalFrame, JMenuItem> entry
386            : schemaWindowMap.entrySet())
387        {
388            if ((entry.getValue()).getText().equals(sfname)) {
389                sf = entry.getKey();
390                break;
391            }
392        }
393        return sf;
394    }
395
396    // Variables declaration - do not modify
397    private javax.swing.JScrollPane jScrollPane3;
398    private javax.swing.JScrollPane jScrollPane2;
399    private javax.swing.JTextPane resultTextPane;
400    private javax.swing.JScrollPane jScrollPane1;
401    private javax.swing.JTextPane queryTextPane;
402    private javax.swing.JSplitPane jSplitPane1;
403    private javax.swing.JButton executeButton;
404    private javax.swing.JComboBox schemaList;
405    private JLabel schemaLabel;
406    private JPanel schemaPanel;
407    private javax.swing.JScrollPane schemaScrollPane1;
408    private javax.swing.JButton connectButton;
409    private JPopupMenu jPopupMenu;
410
411    // End of variables declaration
412
413}
414
415// End QueryPanel.java