/*! * 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) 2002-2016 Pentaho Corporation.. All rights reserved. */ package org.pentaho.reporting.ui.datasources.pmd; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rtextarea.RTextScrollPane; import org.pentaho.metadata.repository.IMetadataDomainRepository; import org.pentaho.reporting.engine.classic.core.ReportDataFactoryException; import org.pentaho.reporting.engine.classic.core.designtime.DesignTimeContext; import org.pentaho.reporting.engine.classic.core.designtime.DesignTimeUtil; import org.pentaho.reporting.engine.classic.core.designtime.datafactory.DataFactoryEditorSupport; import org.pentaho.reporting.engine.classic.core.modules.gui.commonswing.ExceptionDialog; import org.pentaho.reporting.engine.classic.extensions.datasources.pmd.PmdConnectionProvider; import org.pentaho.reporting.engine.classic.extensions.datasources.pmd.PmdDataFactory; import org.pentaho.reporting.libraries.base.util.FilesystemFilter; import org.pentaho.reporting.libraries.base.util.IOUtils; import org.pentaho.reporting.libraries.base.util.StringUtils; import org.pentaho.reporting.libraries.base.util.XMLParserFactoryProducer; import org.pentaho.reporting.libraries.designtime.swing.BorderlessButton; import org.pentaho.reporting.libraries.designtime.swing.CommonDialog; import org.pentaho.reporting.libraries.designtime.swing.SmartComboBox; import org.pentaho.reporting.libraries.designtime.swing.VerticalLayout; import org.pentaho.reporting.libraries.designtime.swing.background.BackgroundCancellableProcessHelper; import org.pentaho.reporting.libraries.designtime.swing.background.DataPreviewDialog; import org.pentaho.reporting.libraries.designtime.swing.event.DocumentChangeHandler; import org.pentaho.reporting.libraries.designtime.swing.filechooser.CommonFileChooser; import org.pentaho.reporting.libraries.designtime.swing.filechooser.FileChooserService; import org.pentaho.reporting.ui.datasources.pmd.util.CreateMqlEditorTask; import org.pentaho.reporting.ui.datasources.pmd.util.DataSetQuery; import org.pentaho.reporting.ui.datasources.pmd.util.LimitRowsCheckBoxActionListener; import org.pentaho.reporting.ui.datasources.pmd.util.LoadRepositoryRunnable; import org.pentaho.reporting.ui.datasources.pmd.util.QueryLanguageListCellRenderer; import org.pentaho.reporting.ui.datasources.pmd.util.QueryNameListCellRenderer; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.DefaultComboBoxModel; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.ListModel; import javax.swing.ListSelectionModel; import javax.swing.SpinnerNumberModel; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.filechooser.FileFilter; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dialog; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.StringReader; import java.io.StringWriter; import java.net.URL; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.TreeMap; /** * @author David Kincade */ public class PmdDataSourceEditor extends CommonDialog { private class BrowseAction extends AbstractAction { protected BrowseAction() { putValue( Action.NAME, Messages.getString( "PmdDataSourceEditor.Browse.Name" ) ); } public void actionPerformed( final ActionEvent e ) { final File initiallySelectedFile; final File reportContextFile = DesignTimeUtil.getContextAsFile( context.getReport() ); if ( StringUtils.isEmpty( filenameField.getText(), true ) == false ) { if ( reportContextFile != null ) { initiallySelectedFile = new File( reportContextFile.getParentFile(), filenameField.getText() ); } else { initiallySelectedFile = new File( filenameField.getText() ); } } else { initiallySelectedFile = null; // NON-NLS } final FileFilter[] fileFilters = new FileFilter[] { new FilesystemFilter( new String[] { ".xmi" }, // NON-NLS Messages.getString( "PmdDataSourceEditor.XmiFileName" ) + " (*.xmi)", true ) }; // NON-NLS final CommonFileChooser fileChooser = FileChooserService.getInstance().getFileChooser( "xmifile" ); fileChooser.setSelectedFile( initiallySelectedFile ); fileChooser.setFilters( fileFilters ); if ( fileChooser.showDialog( PmdDataSourceEditor.this, JFileChooser.OPEN_DIALOG ) == false ) { return; } final File file = fileChooser.getSelectedFile(); if ( file == null ) { return; } final String path; if ( reportContextFile != null ) { path = IOUtils.getInstance().createRelativePath( file.getPath(), reportContextFile.getAbsolutePath() ); } else { path = file.getPath(); } filenameField.setText( path ); } } private class QueryNameListSelectionListener implements ListSelectionListener { public void valueChanged( final ListSelectionEvent e ) { if ( inQueryNameUpdate ) { return; } final DataSetQuery query = (DataSetQuery) queryNameList.getSelectedValue(); if ( query != null ) { queryNameTextField.setText( query.getQueryName() ); queryTextArea.setText( query.getQuery() ); queryScriptTextArea.setText( query.getScript() ); setScriptingLanguage( query.getScriptLanguage(), queryLanguageField ); updateComponents(); } else { queryNameTextField.setText( "" ); queryTextArea.setText( "" ); queryScriptTextArea.setText( "" ); setScriptingLanguage( null, queryLanguageField ); updateComponents(); } } } private class AddQueryAction extends AbstractAction { public AddQueryAction() { final URL resource = PmdDataSourceEditor.class.getResource( "/org/pentaho/reporting/ui/datasources/pmd/resources/Add.png" ); // NON-NLS if ( resource != null ) { putValue( Action.SMALL_ICON, new ImageIcon( resource ) ); } else { putValue( Action.NAME, Messages.getString( "PmdDataSourceEditor.AddQuery.Name" ) ); } putValue( Action.SHORT_DESCRIPTION, Messages.getString( "PmdDataSourceEditor.AddQuery.Description" ) ); } public void actionPerformed( final ActionEvent e ) { // Find a unique query name String queryName = "PmdDataSourceEditor.Query"; for ( int i = 1; i < 1000; ++i ) { final String newQueryName = Messages.getString( "PmdDataSourceEditor.Query" ) + " " + i; if ( !queries.containsKey( newQueryName ) ) { queryName = newQueryName; break; } } final DataSetQuery newQuery = new DataSetQuery( queryName, "", null, null ); queries.put( newQuery.getQueryName(), newQuery ); inModifyingQueryNameList = true; updateQueryList(); queryNameList.setSelectedValue( newQuery, true ); inModifyingQueryNameList = false; updateComponents(); } } private class PrepareAndInvokeMqlEditorTask implements Runnable { private PrepareAndInvokeMqlEditorTask() { } public void run() { final DataSetQuery query = queries.get( queryNameTextField.getText() ); if ( query == null ) { return; } try { final LoadRepositoryRunnable loadRepositoryRunnable = new LoadRepositoryRunnable( context, domainIdTextField.getText(), filenameField.getText() ); final Thread loadRepositoryThread = new Thread( loadRepositoryRunnable ); BackgroundCancellableProcessHelper.executeProcessWithCancelDialog( loadRepositoryThread, null, PmdDataSourceEditor.this, Messages.getString( "PmdDataSourceEditor.PreviewTask" ) ); final IMetadataDomainRepository repository = loadRepositoryRunnable.getRepository(); if ( repository == null ) { return; } SwingUtilities.invokeLater( new CreateMqlEditorTask( repository, context, query, queryTextArea ) ); } catch ( Exception exc ) { context.error( exc ); } } } private class QueryDesignerAction extends AbstractAction { public QueryDesignerAction() { final URL resource = PmdDataSourceModule.class.getResource( "/org/pentaho/reporting/ui/datasources/pmd/resources/Edit.png" ); // NON-NLS if ( resource != null ) { putValue( Action.SMALL_ICON, new ImageIcon( resource ) ); } else { putValue( Action.NAME, Messages.getString( "PmdDataSourceEditor.EditQuery.Name" ) ); } putValue( Action.SHORT_DESCRIPTION, Messages.getString( "PmdDataSourceEditor.EditQuery.Description" ) ); setEnabled( false ); } public void actionPerformed( final ActionEvent e ) { final Thread t = new Thread( new PrepareAndInvokeMqlEditorTask() ); t.start(); } } private class RemoveQueryAction extends AbstractAction { public RemoveQueryAction() { final URL resource = PmdDataSourceEditor.class.getResource( "/org/pentaho/reporting/ui/datasources/pmd/resources/Remove.png" ); // NON-NLS if ( resource != null ) { putValue( Action.SMALL_ICON, new ImageIcon( resource ) ); } else { putValue( Action.NAME, Messages.getString( "PmdDataSourceEditor.RemoveQuery.Name" ) ); } putValue( Action.SHORT_DESCRIPTION, Messages.getString( "PmdDataSourceEditor.RemoveQuery.Description" ) ); } public void actionPerformed( final ActionEvent e ) { final DataSetQuery query = (DataSetQuery) queryNameList.getSelectedValue(); if ( query != null ) { queries.remove( query.getQueryName() ); } inModifyingQueryNameList = true; updateQueryList(); queryNameList.clearSelection(); inModifyingQueryNameList = false; updateComponents(); } } private class QueryDocumentListener extends DocumentChangeHandler { private QueryDocumentListener() { } protected void handleChange( final DocumentEvent e ) { final DataSetQuery query = (DataSetQuery) queryNameList.getSelectedValue(); if ( query != null ) { query.setQuery( queryTextArea.getText() ); } } } private class QueryScriptDocumentListener extends DocumentChangeHandler { private QueryScriptDocumentListener() { } protected void handleChange( final DocumentEvent e ) { final DataSetQuery query = (DataSetQuery) queryNameList.getSelectedValue(); if ( query != null ) { query.setScript( queryScriptTextArea.getText() ); } } } private class QueryNameTextFieldDocumentListener extends DocumentChangeHandler { protected void handleChange( final DocumentEvent e ) { if ( inModifyingQueryNameList ) { return; } final String queryName = queryNameTextField.getText(); final DataSetQuery currentQuery = (DataSetQuery) queryNameList.getSelectedValue(); if ( currentQuery == null ) { return; } if ( queryName.equals( currentQuery.getQueryName() ) ) { return; } if ( queries.containsKey( queryName ) ) { return; } inQueryNameUpdate = true; queries.remove( currentQuery.getQueryName() ); currentQuery.setQueryName( queryName ); queries.put( currentQuery.getQueryName(), currentQuery ); updateQueryList(); queryNameList.setSelectedValue( currentQuery, true ); inQueryNameUpdate = false; } } private class DomainTextFieldDocumentListener extends DocumentChangeHandler implements Runnable { protected void handleChange( final DocumentEvent e ) { updateComponents(); SwingUtilities.invokeLater( this ); } public void run() { updateQueries(); } } private class FilenameDocumentListener extends DocumentChangeHandler { protected void handleChange( final DocumentEvent e ) { updateComponents(); } } private class PreviewAction extends AbstractAction { private PreviewAction() { putValue( Action.NAME, Messages.getString( "PmdDataSourceEditor.Preview.Name" ) ); } public void actionPerformed( final ActionEvent evt ) { try { final DataPreviewDialog previewDialog = new DataPreviewDialog( PmdDataSourceEditor.this ); final String query = queryNameTextField.getText(); Integer theMaxRows = 0; if ( maxPreviewRowsSpinner.isEnabled() ) { theMaxRows = (Integer) maxPreviewRowsSpinner.getValue(); } final PmdDataFactory dataFactory = createDataFactory(); DataFactoryEditorSupport.configureDataFactoryForPreview( dataFactory, context ); final PmdPreviewWorker worker = new PmdPreviewWorker( dataFactory, query, 0, theMaxRows ); previewDialog.showData( worker ); final ReportDataFactoryException factoryException = worker.getException(); if ( factoryException != null ) { ExceptionDialog.showExceptionDialog( PmdDataSourceEditor.this, Messages.getString( "PmdDataSourceEditor.PreviewError.Title" ), Messages.getString( "PmdDataSourceEditor.PreviewError.Message" ), factoryException ); } } catch ( Exception e ) { context.error( e ); ExceptionDialog.showExceptionDialog( PmdDataSourceEditor.this, Messages.getString( "PmdDataSourceEditor.PreviewError.Title" ), Messages.getString( "PmdDataSourceEditor.PreviewError.Message" ), e ); } } } private class UpdateScriptLanguageHandler implements ActionListener, ListSelectionListener { private UpdateScriptLanguageHandler() { } public void actionPerformed( final ActionEvent e ) { final DataSetQuery query = (DataSetQuery) queryNameList.getSelectedValue(); if ( query != null ) { final ScriptEngineFactory selectedItem = (ScriptEngineFactory) queryLanguageField.getSelectedItem(); if ( selectedItem != null ) { query.setScriptLanguage( selectedItem.getLanguageName() ); } else { query.setScriptLanguage( null ); } } updateComponents(); } /** * Called whenever the value of the selection changes. * * @param e the event that characterizes the change. */ public void valueChanged( final ListSelectionEvent e ) { updateComponents(); } } private class GlobalTemplateAction extends AbstractAction { private URL resource; private GlobalTemplateAction() { putValue( Action.NAME, Messages.getString( "PmdDataSourceEditor.InsertTemplate" ) ); } public void actionPerformed( final ActionEvent e ) { if ( resource == null ) { return; } if ( StringUtils.isEmpty( globalScriptTextArea.getText(), true ) == false ) { if ( JOptionPane.showConfirmDialog( PmdDataSourceEditor.this, Messages.getString( "PmdDataSourceEditor.OverwriteScript" ), Messages.getString( "PmdDataSourceEditor.OverwriteScriptTitle" ), JOptionPane.YES_NO_OPTION ) != JOptionPane.YES_OPTION ) { return; } } try { final InputStreamReader r = new InputStreamReader( resource.openStream(), "UTF-8" ); try { final StringWriter w = new StringWriter(); IOUtils.getInstance().copyWriter( r, w ); globalScriptTextArea.setText( w.toString() ); } finally { r.close(); } } catch ( IOException ex ) { logger.warn( "Unable to read template.", ex ); } } public void update() { String key = globalScriptTextArea.getSyntaxEditingStyle(); if ( key.startsWith( "text/" ) ) { key = key.substring( 5 ); } resource = PmdDataSourceEditor.class.getResource( "resources/global-template-" + key + ".txt" ); setEnabled( resource != null ); } } private class QueryTemplateAction extends AbstractAction { private URL resource; private QueryTemplateAction() { putValue( Action.NAME, Messages.getString( "PmdDataSourceEditor.InsertTemplate" ) ); } public void actionPerformed( final ActionEvent e ) { if ( resource == null ) { return; } if ( StringUtils.isEmpty( queryScriptTextArea.getText(), true ) == false ) { if ( JOptionPane.showConfirmDialog( PmdDataSourceEditor.this, Messages.getString( "PmdDataSourceEditor.OverwriteScript" ), Messages.getString( "PmdDataSourceEditor.OverwriteScriptTitle" ), JOptionPane.YES_NO_OPTION ) != JOptionPane.YES_OPTION ) { return; } } try { final InputStreamReader r = new InputStreamReader( resource.openStream(), "UTF-8" ); try { final StringWriter w = new StringWriter(); IOUtils.getInstance().copyWriter( r, w ); queryScriptTextArea.insert( w.toString(), 0 ); } finally { r.close(); } } catch ( IOException ex ) { logger.warn( "Unable to read template.", ex ); } } public void update() { String key = queryScriptTextArea.getSyntaxEditingStyle(); if ( key.startsWith( "text/" ) ) { key = key.substring( 5 ); } resource = PmdDataSourceEditor.class.getResource( "resources/query-template-" + key + ".txt" ); setEnabled( resource != null ); } } private static final Log logger = LogFactory.getLog( PmdDataSourceEditor.class ); private JList queryNameList; private JButton queryRemoveButton; private JButton queryDesignerButton; private JButton queryAddButton; private JTextField domainIdTextField; private JTextField queryNameTextField; private JTextField filenameField; private RSyntaxTextArea queryTextArea; private Map<String, DataSetQuery> queries; private boolean inQueryNameUpdate; private boolean inModifyingQueryNameList; private DesignTimeContext context; private JSpinner maxPreviewRowsSpinner; private Action previewAction; private RSyntaxTextArea globalScriptTextArea; private SmartComboBox globalLanguageField; private RSyntaxTextArea queryScriptTextArea; private SmartComboBox queryLanguageField; private QueryLanguageListCellRenderer queryLanguageListCellRenderer; private GlobalTemplateAction globalTemplateAction; private QueryTemplateAction queryTemplateAction; public PmdDataSourceEditor( final DesignTimeContext context ) { init( context ); } public PmdDataSourceEditor( final DesignTimeContext context, final Dialog owner ) { super( owner ); init( context ); } public PmdDataSourceEditor( final DesignTimeContext context, final Frame owner ) { super( owner ); init( context ); } private void init( final DesignTimeContext context ) { if ( context == null ) { throw new NullPointerException(); } this.context = context; setModal( true ); setTitle( Messages.getString( "PmdDataSourceEditor.Title" ) ); maxPreviewRowsSpinner = new JSpinner( new SpinnerNumberModel( 10000, 1, Integer.MAX_VALUE, 1 ) ); previewAction = new PreviewAction(); globalTemplateAction = new GlobalTemplateAction(); queryTemplateAction = new QueryTemplateAction(); filenameField = new JTextField( null, 0 ); filenameField.setColumns( 30 ); filenameField.getDocument().addDocumentListener( new FilenameDocumentListener() ); queryNameList = new JList(); queryNameList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); queryNameList.setVisibleRowCount( 5 ); queryNameList.addListSelectionListener( new QueryNameListSelectionListener() ); queryNameList.setCellRenderer( new QueryNameListCellRenderer() ); queryAddButton = new BorderlessButton( new AddQueryAction() ); queryRemoveButton = new BorderlessButton( new RemoveQueryAction() ); queryNameTextField = new JTextField( null, 0 ); queryNameTextField.setColumns( 35 ); queryNameTextField.getDocument().addDocumentListener( new QueryNameTextFieldDocumentListener() ); domainIdTextField = new JTextField( null, 0 ); domainIdTextField.setColumns( 35 ); domainIdTextField.getDocument().addDocumentListener( new DomainTextFieldDocumentListener() ); queryTextArea = new RSyntaxTextArea(); queryTextArea.setSyntaxEditingStyle( SyntaxConstants.SYNTAX_STYLE_XML ); queryTextArea.setWrapStyleWord( true ); queryTextArea.setLineWrap( true ); queryTextArea.setRows( 5 ); queryTextArea.getDocument().addDocumentListener( new QueryDocumentListener() ); queryDesignerButton = new JButton( new QueryDesignerAction() ); queryDesignerButton.setEnabled( false ); queryDesignerButton.setBorder( new EmptyBorder( 0, 0, 0, 0 ) ); globalScriptTextArea = new RSyntaxTextArea(); globalScriptTextArea.setSyntaxEditingStyle( SyntaxConstants.SYNTAX_STYLE_NONE ); globalLanguageField = new SmartComboBox( new DefaultComboBoxModel( getScriptEngineLanguages() ) ); globalLanguageField.setRenderer( new QueryLanguageListCellRenderer() ); globalLanguageField.addActionListener( new UpdateScriptLanguageHandler() ); queryScriptTextArea = new RSyntaxTextArea(); queryScriptTextArea.setSyntaxEditingStyle( SyntaxConstants.SYNTAX_STYLE_NONE ); queryScriptTextArea.getDocument().addDocumentListener( new QueryScriptDocumentListener() ); queryLanguageListCellRenderer = new QueryLanguageListCellRenderer(); queryLanguageField = new SmartComboBox( new DefaultComboBoxModel( getScriptEngineLanguages() ) ); queryLanguageField.setRenderer( queryLanguageListCellRenderer ); queryLanguageField.addActionListener( new UpdateScriptLanguageHandler() ); super.init(); } protected String getDialogId() { return "PmdDataSourceEditor"; } private ScriptEngineFactory[] getScriptEngineLanguages() { final LinkedHashSet<ScriptEngineFactory> langSet = new LinkedHashSet<ScriptEngineFactory>(); langSet.add( null ); final List<ScriptEngineFactory> engineFactories = new ScriptEngineManager().getEngineFactories(); for ( final ScriptEngineFactory engineFactory : engineFactories ) { langSet.add( engineFactory ); } return langSet.toArray( new ScriptEngineFactory[ langSet.size() ] ); } protected Component createContentPane() { final JPanel queryTextAreaHeaderPanel = new JPanel( new BorderLayout() ); queryTextAreaHeaderPanel .add( new JLabel( Messages.getString( "PmdDataSourceEditor.QueryLabel" ) ), BorderLayout.WEST ); queryTextAreaHeaderPanel.add( queryDesignerButton, BorderLayout.EAST ); final JPanel queryConfigurationPanel = new JPanel(); queryConfigurationPanel.setLayout( new BorderLayout() ); queryConfigurationPanel.add( queryTextAreaHeaderPanel, BorderLayout.NORTH ); queryConfigurationPanel.add( new RTextScrollPane( 700, 500, queryTextArea, true ), BorderLayout.CENTER ); final JTabbedPane queryScriptTabPane = new JTabbedPane(); queryScriptTabPane.addTab( Messages.getString( "PmdDataSourceEditor.StaticQuery" ), queryConfigurationPanel ); queryScriptTabPane.addTab( Messages.getString( "PmdDataSourceEditor.QueryScripting" ), createQueryScriptTab() ); final JPanel queryAreaPanel = new JPanel(); queryAreaPanel.setLayout( new BorderLayout() ); queryAreaPanel.add( createGlobalPropertiesPanel(), BorderLayout.NORTH ); queryAreaPanel.add( queryScriptTabPane, BorderLayout.CENTER ); final JTabbedPane tabbedPane = new JTabbedPane(); tabbedPane.addTab( Messages.getString( "PmdDataSourceEditor.DataSource" ), queryAreaPanel ); tabbedPane.addTab( Messages.getString( "PmdDataSourceEditor.GlobalScripting" ), createGlobalScriptTab() ); final JPanel contentPanel = new JPanel( new BorderLayout() ); contentPanel.add( tabbedPane, BorderLayout.CENTER ); contentPanel.add( createPreviewButtonsPanel(), BorderLayout.SOUTH ); contentPanel.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) ); return contentPanel; } private JPanel createQueryScriptTab() { final JPanel queryHeader2 = new JPanel( new BorderLayout() ); queryHeader2.add( new JLabel( Messages.getString( "PmdDataSourceEditor.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( "PmdDataSourceEditor.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( "PmdDataSourceEditor.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( "PmdDataSourceEditor.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 ); return globalScriptContentHolder; } private JPanel createGlobalPropertiesPanel() { final JPanel filePanel = new JPanel(); filePanel.setLayout( new BoxLayout( filePanel, BoxLayout.X_AXIS ) ); filePanel.add( filenameField ); filePanel.add( new JButton( new BrowseAction() ) ); final JPanel queryListButtonsPanel = new JPanel( new FlowLayout( FlowLayout.RIGHT ) ); queryListButtonsPanel.add( queryAddButton ); queryListButtonsPanel.add( queryRemoveButton ); final JPanel queryListButtonsPanelWrapper = new JPanel( new BorderLayout() ); queryListButtonsPanelWrapper .add( new JLabel( Messages.getString( "PmdDataSourceEditor.AvailableQueries" ) ), BorderLayout.WEST ); queryListButtonsPanelWrapper.add( queryListButtonsPanel, BorderLayout.EAST ); final JPanel dataSourceConfigurationPanel = new JPanel(); dataSourceConfigurationPanel.setLayout( new VerticalLayout( 5, VerticalLayout.BOTH, VerticalLayout.TOP ) ); dataSourceConfigurationPanel.add( new JLabel( Messages.getString( "PmdDataSourceEditor.XmiFileLabel" ) ) ); dataSourceConfigurationPanel.add( filePanel ); dataSourceConfigurationPanel.add( new JLabel( Messages.getString( "PmdDataSourceEditor.DomainId" ) ) ); dataSourceConfigurationPanel.add( domainIdTextField ); dataSourceConfigurationPanel.add( queryListButtonsPanelWrapper ); dataSourceConfigurationPanel.add( new JScrollPane( queryNameList ) ); dataSourceConfigurationPanel.add( new JLabel( Messages.getString( "PmdDataSourceEditor.QueryName" ) ) ); dataSourceConfigurationPanel.add( queryNameTextField ); return dataSourceConfigurationPanel; } private JPanel createPreviewButtonsPanel() { final JPanel previewButtonsPanel = new JPanel( new FlowLayout( FlowLayout.RIGHT ) ); previewButtonsPanel.add( new JCheckBox( new LimitRowsCheckBoxActionListener( maxPreviewRowsSpinner ) ) ); previewButtonsPanel.add( maxPreviewRowsSpinner ); previewButtonsPanel.add( new JButton( previewAction ) ); return previewButtonsPanel; } public PmdDataFactory performConfiguration( final PmdDataFactory dataFactory, final String selectedQuery ) { // Initialize the internal storage queries = new TreeMap<String, DataSetQuery>(); // Load the current configuration if ( dataFactory != null ) { filenameField.setText( dataFactory.getXmiFile() ); domainIdTextField.setText( dataFactory.getDomainId() ); setGlobalScriptingLanguage( dataFactory.getGlobalScriptLanguage() ); globalScriptTextArea.setText( dataFactory.getGlobalScript() ); final String[] queryNames = dataFactory.getQueryNames(); for ( int i = 0; i < queryNames.length; i++ ) { final String queryName = queryNames[ i ]; final String query = dataFactory.getQuery( queryName ); final String scriptLanguage = dataFactory.getScriptingLanguage( queryName ); final String script = dataFactory.getScript( queryName ); queries.put( queryName, new DataSetQuery( queryName, query, scriptLanguage, script ) ); } } // Prepare the data and the enable the proper buttons updateComponents(); updateQueryList(); setSelectedQuery( selectedQuery ); if ( !performEdit() ) { return null; } return createDataFactory(); } 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 String getGlobalScriptingLanguage() { final ScriptEngineFactory selectedValue = (ScriptEngineFactory) globalLanguageField.getSelectedItem(); if ( selectedValue == null ) { return null; } return selectedValue.getLanguageName(); } private PmdDataFactory createDataFactory() { final PmdDataFactory returnDataFactory = new PmdDataFactory(); returnDataFactory.setXmiFile( filenameField.getText() ); returnDataFactory.setDomainId( domainIdTextField.getText() ); returnDataFactory.setConnectionProvider( new PmdConnectionProvider() ); returnDataFactory.setGlobalScriptLanguage( getGlobalScriptingLanguage() ); if ( StringUtils.isEmpty( globalScriptTextArea.getText() ) == false ) { returnDataFactory.setGlobalScript( globalScriptTextArea.getText() ); } for ( final DataSetQuery query : this.queries.values() ) { returnDataFactory .setQuery( query.getQueryName(), query.getQuery(), query.getScriptLanguage(), query.getScript() ); } return returnDataFactory; } protected void updateQueryList() { if ( !queries.isEmpty() ) { queryNameList.setListData( queries.values().toArray( new DataSetQuery[ queries.size() ] ) ); } else { queryNameList.setListData( new Object[ 0 ] ); } } private void setSelectedQuery( final String query ) { final ListModel listModel = queryNameList.getModel(); for ( int i = 0; i < listModel.getSize(); i++ ) { final DataSetQuery dataSet = (DataSetQuery) listModel.getElementAt( i ); if ( dataSet.getQueryName().equals( query ) ) { queryNameList.setSelectedValue( dataSet, true ); break; } } } protected void updateComponents() { final boolean querySelected = queryNameList.getSelectedIndex() != -1; final boolean hasQueries = queryNameList.getModel().getSize() > 0; final boolean isFileSelected = !StringUtils.isEmpty( filenameField.getText(), true ); final boolean hasDomain = !StringUtils.isEmpty( domainIdTextField.getText(), true ); queryLanguageListCellRenderer.setDefaultValue( (ScriptEngineFactory) globalLanguageField.getSelectedItem() ); domainIdTextField.setEnabled( isFileSelected ); previewAction.setEnabled( isFileSelected && querySelected ); queryNameTextField.setEnabled( querySelected ); queryTextArea.setEnabled( querySelected ); queryRemoveButton.setEnabled( querySelected ); queryDesignerButton.setEnabled( hasDomain && querySelected && isFileSelected ); queryAddButton.setEnabled( true ); globalScriptTextArea.setSyntaxEditingStyle( mapLanguageToSyntaxHighlighting( (ScriptEngineFactory) globalLanguageField.getSelectedItem() ) ); final ScriptEngineFactory queryScriptLanguage = (ScriptEngineFactory) queryLanguageField.getSelectedItem(); if ( queryScriptLanguage == null ) { queryScriptTextArea.setSyntaxEditingStyle( globalScriptTextArea.getSyntaxEditingStyle() ); } else { queryScriptTextArea.setSyntaxEditingStyle( mapLanguageToSyntaxHighlighting( queryScriptLanguage ) ); } getConfirmAction().setEnabled( hasQueries && isFileSelected ); queryScriptTextArea.setEnabled( querySelected ); queryLanguageField.setEnabled( querySelected ); queryTemplateAction.update(); if ( querySelected == false ) { queryTemplateAction.setEnabled( false ); } globalTemplateAction.update(); } private String mapLanguageToSyntaxHighlighting( final ScriptEngineFactory script ) { if ( script == null ) { return SyntaxConstants.SYNTAX_STYLE_NONE; } final String language = script.getLanguageName(); if ( "ECMAScript".equalsIgnoreCase( language ) || "js".equalsIgnoreCase( language ) || "rhino".equalsIgnoreCase( language ) || "javascript".equalsIgnoreCase( language ) ) { return SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT; } if ( "groovy".equalsIgnoreCase( language ) ) { return SyntaxConstants.SYNTAX_STYLE_GROOVY; } return SyntaxConstants.SYNTAX_STYLE_NONE; } protected void updateQueries() { try { final DocumentBuilderFactory factory = XMLParserFactoryProducer.createSecureDocBuilderFactory(); final DocumentBuilder documentBuilder = factory.newDocumentBuilder(); final DataSetQuery[] objects = queries.values().toArray( new DataSetQuery[ queries.size() ] ); for ( int i = 0; i < objects.length; i++ ) { final DataSetQuery object = objects[ i ]; final String text = object.getQuery(); if ( StringUtils.isEmpty( text, true ) ) { continue; } try { final Document doc = documentBuilder.parse( new InputSource( new StringReader( text ) ) ); final NodeList list = doc.getDocumentElement().getElementsByTagName( "domain_id" ); if ( list.getLength() == 0 ) { continue; } list.item( 0 ).setTextContent( domainIdTextField.getText() ); final TransformerFactory tfactory = TransformerFactory.newInstance(); final StringWriter stringWriter = new StringWriter(); final StreamResult result = new StreamResult(); result.setWriter( stringWriter ); tfactory.newTransformer().transform( new DOMSource( doc ), result ); object.setQuery( stringWriter.getBuffer().toString() ); } catch ( Exception e ) { context.error( e ); } } } catch ( Exception e ) { context.error( e ); } final Object o = queryNameList.getSelectedValue(); if ( o != null ) { final DataSetQuery q = (DataSetQuery) o; queryTextArea.setText( q.getQuery() ); } } }