/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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 Lesser General Public License for more details.
*
* Copyright (c) 2006 - 2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.engine.classic.core.designtime.datafactory.editor.ui;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.script.ScriptEngineFactory;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.DataFactoryEditorSupport;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.editor.model.Query;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.editor.model.QueryDialogModel;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.editor.model.QueryDialogModelEvent;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.editor.model.QueryDialogModelListenerAdapter;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
import org.pentaho.reporting.libraries.base.util.StringUtils;
import org.pentaho.reporting.libraries.designtime.swing.BorderlessButton;
import org.pentaho.reporting.libraries.designtime.swing.SmartComboBox;
import org.pentaho.reporting.libraries.designtime.swing.VerticalLayout;
public abstract class QueryEditorPanel<T> extends JPanel
{
private class QuerySelectedHandler implements ListSelectionListener
{
private QueryDialogModel<T> dialogModel;
private JList queryNameList;
private QuerySelectedHandler(final QueryDialogModel<T> dialogModel,
final JList queryNameList)
{
this.dialogModel = dialogModel;
this.queryNameList = queryNameList;
}
public void valueChanged(final ListSelectionEvent e)
{
dialogModel.setSelectedQuery((Query<T>) queryNameList.getSelectedValue());
}
}
private class UpdateQueryScriptLanguageHandler implements ActionListener
{
private UpdateQueryScriptLanguageHandler()
{
}
public void actionPerformed(final ActionEvent e)
{
final Query<T> query = dialogModel.getSelectedQuery();
if (query == null)
{
return;
}
String selectedQueryScriptLanguage = getSelectedQueryScriptLanguage();
if (ObjectUtilities.equal(selectedQueryScriptLanguage, query.getQueryLanguage()))
{
return;
}
Query<T> newQuery = query.updateQueryScript(selectedQueryScriptLanguage, query.getQueryScript());
dialogModel.updateSelectedQuery(newQuery);
}
}
private class UpdateGlobalScriptLanguageHandler implements ActionListener
{
private UpdateGlobalScriptLanguageHandler()
{
}
public void actionPerformed(final ActionEvent e)
{
dialogModel.setGlobalScripting(getSelectedGlobalScriptLanguage(), dialogModel.getGlobalScript());
}
}
private class QueryNameUpdateHandler extends TextFieldBinding
{
private QueryNameUpdateHandler()
{
}
protected void performUpdate()
{
final Query<T> selectedQuery = dialogModel.getSelectedQuery();
if (selectedQuery == null)
{
return;
}
String text = queryNameTextField.getText();
if (ObjectUtilities.equal(text, selectedQuery.getName()))
{
return;
}
dialogModel.updateSelectedQuery(selectedQuery.updateName(text));
}
}
private class GlobalScriptUpdateHandler extends TextFieldBinding
{
private GlobalScriptUpdateHandler()
{
}
protected void performUpdate()
{
String text = globalScriptTextArea.getText();
if (StringUtils.isEmpty(text))
{
text = null;
}
if (ObjectUtilities.equal(text, dialogModel.getGlobalScript()))
{
return;
}
dialogModel.setGlobalScripting(getSelectedGlobalScriptLanguage(), text);
}
}
private class QueryScriptUpdateHandler extends TextFieldBinding
{
private QueryScriptUpdateHandler()
{
}
protected void performUpdate()
{
final Query<T> selectedQuery = dialogModel.getSelectedQuery();
if (selectedQuery == null)
{
return;
}
String text = queryScriptTextArea.getText();
if (StringUtils.isEmpty(text))
{
text = null;
}
if (ObjectUtilities.equal(text, selectedQuery.getQueryScript()))
{
return;
}
dialogModel.updateSelectedQuery(selectedQuery.updateQueryScript(getSelectedQueryScriptLanguage(), text));
}
}
private class DialogModelChangesDispatcher<T> extends QueryDialogModelListenerAdapter<T>
{
private DialogModelChangesDispatcher()
{
}
public void globalScriptChanged(final QueryDialogModelEvent<T> event)
{
String globalScript = dialogModel.getGlobalScript();
String globalScriptLanguage = dialogModel.getGlobalScriptLanguage();
if (ObjectUtilities.equal(getSelectedGlobalScriptLanguage(), globalScriptLanguage) == false)
{
setGlobalScriptingLanguage(globalScriptLanguage);
ScriptEngineFactory globalLanguage = (ScriptEngineFactory) globalLanguageField.getSelectedItem();
globalScriptTextArea.setSyntaxEditingStyle
(DataFactoryEditorSupport.mapLanguageToSyntaxHighlighting(globalLanguage));
queryLanguageListCellRenderer.setDefaultValue(globalLanguage);
}
if (ObjectUtilities.equal(globalScriptTextArea.getText(), globalScript) == false)
{
globalScriptTextArea.setText(globalScript);
}
globalTemplateAction.update((ScriptEngineFactory) globalLanguageField.getSelectedItem());
}
public void queryUpdated(final QueryDialogModelEvent<T> event)
{
if (ObjectUtilities.equal(event.getNewQuery(), dialogModel.getSelectedQuery()))
{
selectionChanged(event);
}
}
public void selectionChanged(final QueryDialogModelEvent<T> event)
{
Query<T> newQuery = event.getNewQuery();
if (newQuery == null)
{
queryScriptTextArea.setEnabled(false);
queryScriptTextArea.setText(null);
queryLanguageField.setEnabled(false);
setQueryScriptingLanguage(null);
queryNameTextField.setEnabled(false);
queryNameTextField.setText(null);
queryNameList.setSelectedIndex(-1);
}
else
{
queryScriptTextArea.setEnabled(true);
queryScriptTextArea.setText(newQuery.getQueryScript());
queryLanguageField.setEnabled(true);
setQueryScriptingLanguage(newQuery.getQueryLanguage());
queryNameTextField.setEnabled(true);
queryNameTextField.setText(newQuery.getName());
queryNameList.setSelectedIndex(event.getNewIndex());
final ScriptEngineFactory queryScriptLanguage = (ScriptEngineFactory) queryLanguageField.getSelectedItem();
if (queryScriptLanguage == null)
{
queryScriptTextArea.setSyntaxEditingStyle(globalScriptTextArea.getSyntaxEditingStyle());
}
else
{
queryScriptTextArea.setSyntaxEditingStyle(DataFactoryEditorSupport.mapLanguageToSyntaxHighlighting(queryScriptLanguage));
}
}
queryTemplateAction.update((ScriptEngineFactory) queryLanguageField.getSelectedItem());
updateSelectedQueryFromModel();
}
}
private QueryDialogModel<T> dialogModel;
private JList queryNameList;
private JTextField queryNameTextField;
private SmartComboBox globalLanguageField;
private RSyntaxTextArea globalScriptTextArea;
private RSyntaxTextArea queryScriptTextArea;
private SmartComboBox queryLanguageField;
private QueryLanguageListCellRenderer queryLanguageListCellRenderer;
private GlobalTemplateAction globalTemplateAction;
private QueryTemplateAction queryTemplateAction;
protected QueryEditorPanel(final QueryDialogModel<T> dialogModel)
{
if (dialogModel == null)
{
throw new NullPointerException();
}
this.dialogModel = dialogModel;
init();
}
@SuppressWarnings("unchecked")
private void init()
{
globalTemplateAction = new GlobalTemplateAction(this, dialogModel);
queryTemplateAction = new QueryTemplateAction(this, dialogModel);
queryNameList = new JList(dialogModel.getQueries());
queryNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
queryNameList.setVisibleRowCount(5);
queryNameList.setCellRenderer(new QueryListCellRenderer());
queryNameList.addListSelectionListener(new QuerySelectedHandler(dialogModel, queryNameList));
queryNameTextField = new JTextField();
queryNameTextField.setColumns(35);
queryNameTextField.setEnabled(dialogModel.isQuerySelected());
queryNameTextField.getDocument().addDocumentListener(new QueryNameUpdateHandler());
globalScriptTextArea = new RSyntaxTextArea();
globalScriptTextArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE);
globalScriptTextArea.getDocument().addDocumentListener(new GlobalScriptUpdateHandler());
globalLanguageField = new SmartComboBox(new DefaultComboBoxModel(DataFactoryEditorSupport.getScriptEngineLanguages()));
globalLanguageField.setRenderer(new QueryLanguageListCellRenderer());
globalLanguageField.addActionListener(new UpdateGlobalScriptLanguageHandler());
queryScriptTextArea = new RSyntaxTextArea();
queryScriptTextArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE);
queryScriptTextArea.getDocument().addDocumentListener(new QueryScriptUpdateHandler());
queryLanguageField = new SmartComboBox(new DefaultComboBoxModel(DataFactoryEditorSupport.getScriptEngineLanguages()));
queryLanguageListCellRenderer = new QueryLanguageListCellRenderer();
queryLanguageField.setRenderer(queryLanguageListCellRenderer);
queryLanguageField.addActionListener(new UpdateQueryScriptLanguageHandler());
dialogModel.addQueryDialogModelListener(new DialogModelChangesDispatcher());
initialize();
createComponents();
}
protected abstract void initialize();
public QueryDialogModel<T> getDialogModel()
{
return dialogModel;
}
private String getSelectedGlobalScriptLanguage()
{
Object selectedItem = globalLanguageField.getSelectedItem();
if (selectedItem instanceof ScriptEngineFactory == false)
{
return null;
}
ScriptEngineFactory engineFactory = (ScriptEngineFactory) selectedItem;
return engineFactory.getLanguageName();
}
private String getSelectedQueryScriptLanguage()
{
Object selectedItem = queryLanguageField.getSelectedItem();
if (selectedItem instanceof ScriptEngineFactory == false)
{
return null;
}
ScriptEngineFactory engineFactory = (ScriptEngineFactory) selectedItem;
return engineFactory.getLanguageName();
}
private void setQueryScriptingLanguage(final String lang)
{
setScriptingLanguage(lang, queryLanguageField);
}
private void setGlobalScriptingLanguage(final String lang)
{
setScriptingLanguage(lang, globalLanguageField);
}
protected void setScriptingLanguage(final String lang, final JComboBox languageField)
{
if (lang == null)
{
languageField.setSelectedItem(null);
return;
}
final ListModel model = languageField.getModel();
for (int i = 0; i < model.getSize(); i++)
{
final ScriptEngineFactory elementAt = (ScriptEngineFactory) model.getElementAt(i);
if (elementAt == null)
{
continue;
}
if (elementAt.getNames().contains(lang))
{
languageField.setSelectedItem(elementAt);
return;
}
}
}
private JPanel createQueryScriptTab()
{
final JPanel queryHeader2 = new JPanel(new BorderLayout());
queryHeader2.add(new JLabel(Messages.getString("QueryEditorPanel.QueryScript")), BorderLayout.CENTER);
queryHeader2.add(new JButton(queryTemplateAction), BorderLayout.EAST);
final JPanel queryScriptHeader = new JPanel(new VerticalLayout(5, VerticalLayout.BOTH, VerticalLayout.TOP));
queryScriptHeader.add(new JLabel(Messages.getString("QueryEditorPanel.QueryScriptLanguage")));
queryScriptHeader.add(queryLanguageField);
queryScriptHeader.add(queryHeader2);
final JPanel queryScriptContentHolder = new JPanel(new BorderLayout());
queryScriptContentHolder.add(queryScriptHeader, BorderLayout.NORTH);
queryScriptContentHolder.add(new RTextScrollPane(700, 300, queryScriptTextArea, true), BorderLayout.CENTER);
return queryScriptContentHolder;
}
private JPanel createGlobalScriptTab()
{
final JPanel globalHeader2 = new JPanel(new BorderLayout());
globalHeader2.add(new JLabel(Messages.getString("QueryEditorPanel.GlobalScript")), BorderLayout.CENTER);
globalHeader2.add(new JButton(globalTemplateAction), BorderLayout.EAST);
final JPanel globalScriptHeader = new JPanel(new VerticalLayout(5, VerticalLayout.BOTH, VerticalLayout.TOP));
globalScriptHeader.add(new JLabel(Messages.getString("QueryEditorPanel.GlobalScriptLanguage")));
globalScriptHeader.add(globalLanguageField);
globalScriptHeader.add(globalHeader2);
final JPanel globalScriptContentHolder = new JPanel(new BorderLayout());
globalScriptContentHolder.add(globalScriptHeader, BorderLayout.NORTH);
globalScriptContentHolder.add(new RTextScrollPane(700, 600, globalScriptTextArea, true), BorderLayout.CENTER);
globalScriptContentHolder.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
return globalScriptContentHolder;
}
protected void createComponents()
{
// Create the connection panel
final JPanel queryContentPanel = new JPanel(new BorderLayout());
queryContentPanel.add(BorderLayout.NORTH, createQueryListPanel());
queryContentPanel.add(BorderLayout.CENTER, createQueryDetailsPanel());
final JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab(Messages.getString("QueryEditorPanel.DataSource"), queryContentPanel);
tabbedPane.addTab(Messages.getString("QueryEditorPanel.GlobalScripting"), createGlobalScriptTab());
setLayout(new BorderLayout());
add(BorderLayout.CENTER, tabbedPane);
setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
}
protected JComponent getExtraQueryButtons()
{
return null;
}
protected abstract JComponent getQueryEditor();
private JPanel createQueryDetailsPanel()
{
final JPanel queryNamePanel = new JPanel(new BorderLayout());
queryNamePanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 0, 8));
queryNamePanel.add(new JLabel(Messages.getString("QueryEditorPanel.QueryStringLabel")), BorderLayout.NORTH);
queryNamePanel.add(queryNameTextField, BorderLayout.SOUTH);
final JPanel queryControlsPanel = new JPanel(new BorderLayout());
queryControlsPanel.add(new JLabel(Messages.getString("QueryEditorPanel.QueryDetailsLabel")), BorderLayout.WEST);
JComponent extraQueryButtons = getExtraQueryButtons();
if (extraQueryButtons != null)
{
queryControlsPanel.add(extraQueryButtons, BorderLayout.EAST);
}
final JPanel queryPanel = new JPanel(new BorderLayout());
queryPanel.add(queryControlsPanel, BorderLayout.NORTH);
queryPanel.add(getQueryEditor(), BorderLayout.CENTER);
queryPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 0, 8));
final JTabbedPane queryScriptTabPane = new JTabbedPane();
queryScriptTabPane.addTab(Messages.getString("QueryEditorPanel.StaticQuery"), queryPanel);
queryScriptTabPane.addTab(Messages.getString("QueryEditorPanel.QueryScripting"), createQueryScriptTab());
// Create the query details panel
final JPanel queryDetailsPanel = new JPanel(new BorderLayout());
queryDetailsPanel.add(BorderLayout.NORTH, queryNamePanel);
queryDetailsPanel.add(BorderLayout.CENTER, queryScriptTabPane);
return queryDetailsPanel;
}
private JPanel createQueryListPanel()
{
// Create the query list panel
final JPanel queryButtons = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 5));
queryButtons.add(new BorderlessButton(new QueryAddAction<T>(dialogModel)));
queryButtons.add(new BorderlessButton(new QueryRemoveAction<T>(dialogModel)));
final JPanel queryControlPanel = new JPanel(new BorderLayout());
queryControlPanel.add(new JLabel(Messages.getString("QueryEditorPanel.AvailableQueries")), BorderLayout.WEST);
queryControlPanel.add(queryButtons, BorderLayout.EAST);
final JPanel queryListPanel = new JPanel(new BorderLayout());
queryListPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
queryListPanel.add(BorderLayout.NORTH, queryControlPanel);
queryListPanel.add(BorderLayout.CENTER, new JScrollPane(queryNameList));
return queryListPanel;
}
protected void updateSelectedQueryFromModel()
{
}
}