/*
* 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() {
}
}