Package org.pentaho.reporting.ui.datasources.pmd

Source Code of org.pentaho.reporting.ui.datasources.pmd.PmdDataSourceEditor

/*!
* 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());
    }
  }
}
TOP

Related Classes of org.pentaho.reporting.ui.datasources.pmd.PmdDataSourceEditor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.