/*!
* 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-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.ui.datasources.pmd;
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;
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 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.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;
/**
* @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 = DocumentBuilderFactory.newInstance();
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());
}
}
}