/*!
* 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.kettle;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.Action;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.event.ListSelectionListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.reporting.engine.classic.core.ReportDataFactoryException;
import org.pentaho.reporting.engine.classic.core.designtime.DesignTimeContext;
import org.pentaho.reporting.engine.classic.core.metadata.DataFactoryMetaData;
import org.pentaho.reporting.engine.classic.core.metadata.DataFactoryRegistry;
import org.pentaho.reporting.engine.classic.extensions.datasources.kettle.EmbeddedKettleTransformationProducer;
import org.pentaho.reporting.engine.classic.extensions.datasources.kettle.KettleDataFactory;
import org.pentaho.reporting.engine.classic.extensions.datasources.kettle.KettleTransformationProducer;
/**
* @author Gretchen Moran
*/
public class EmbeddedKettleDataSourceDialog extends KettleDataSourceDialog
{
private static final long serialVersionUID = 5030572665265231736L;
private static final Log logger = LogFactory.getLog(EmbeddedKettleDataSourceDialog.class);
private String datasourceId = null;
private JPanel datasourcePanel;
private EmbeddedKettleQueryEntry lastSelectedQuery = null;
/**
* This listener is registered with the XUL dialog.
*
* @author gmoran
*/
protected class PreviewChangeListener implements PropertyChangeListener
{
@Override
public void propertyChange(PropertyChangeEvent evt)
{
if (evt.getPropertyName().equals("validated"))
{
if (lastSelectedQuery == null)
{
getPreviewAction().setEnabled(false);
}
else
{
getPreviewAction().setEnabled(Boolean.TRUE.equals(evt.getNewValue()));
}
}
}
}
private class EmbeddedQueryNameListSelectionListener extends QueryNameListSelectionListener
{
private EmbeddedQueryNameListSelectionListener()
{
}
protected void handleSelection(final KettleQueryEntry value)
{
if (value == null)
{
setPanelEnabled(false, datasourcePanel);
lastSelectedQuery = null;
return;
}
final DesignTimeContext designTimeContext = getDesignTimeContext();
final Action editParameterAction = getEditParameterAction();
try
{
final EmbeddedKettleQueryEntry selectedQuery = (EmbeddedKettleQueryEntry) value;
setPanelEnabled(true, datasourcePanel);
// This change event gets fired twice, causing the dialog to update twice.. let's stop that.
if ((lastSelectedQuery == null) || (selectedQuery != lastSelectedQuery))
{
lastSelectedQuery = selectedQuery;
updateQueryName(selectedQuery.getName());
datasourcePanel.removeAll();
datasourcePanel.add(selectedQuery.createUI(), BorderLayout.CENTER);
datasourcePanel.revalidate();
datasourcePanel.repaint();
}
getStopOnErrorsCheckBox().setSelected(selectedQuery.isStopOnErrors());
editParameterAction.setEnabled(true);
}
catch (Exception e1)
{
designTimeContext.error(e1);
editParameterAction.setEnabled(false);
}
catch (Throwable t1)
{
designTimeContext.error(new RuntimeException("Fatal error", t1));
editParameterAction.setEnabled(false);
}
}
}
public EmbeddedKettleDataSourceDialog(final DesignTimeContext designTimeContext, final JDialog parent, String id)
{
super(designTimeContext, parent);
datasourceId = id;
setTitle(getDialogTitle());
}
public EmbeddedKettleDataSourceDialog(final DesignTimeContext designTimeContext, final JFrame parent, String id)
{
super(designTimeContext, parent);
datasourceId = id;
setTitle(getDialogTitle());
}
public EmbeddedKettleDataSourceDialog(final DesignTimeContext designTimeContext, String id)
{
super(designTimeContext);
datasourceId = id;
setTitle(getDialogTitle());
}
@Override
protected JPanel createDatasourcePanel()
{
datasourcePanel = new JPanel(new BorderLayout());
return datasourcePanel;
}
private void refreshQueryUIComponents() throws KettleException, ReportDataFactoryException
{
if (datasourcePanel.getComponentCount() <= 0)
{
EmbeddedKettleQueryEntry entry = createNewQueryEntry(findNextName());
datasourcePanel.removeAll();
datasourcePanel.add(entry.createUI(), BorderLayout.CENTER);
datasourcePanel.revalidate();
setPanelEnabled(false, datasourcePanel);
}
}
protected String getDialogTitle()
{
if (datasourceId == null)
{
return "";
}
DataFactoryMetaData meta = DataFactoryRegistry.getInstance().getMetaData(datasourceId);
String displayName = meta.getDisplayName(getLocale());
return Messages.getString("KettleEmbeddedDataSourceDialog.Title", displayName);
}
protected String getDialogId()
{
return "EmbeddedKettleDataSourceDialog";
}
@Override
protected boolean validateInputs(boolean onConfirm)
{
boolean valid = true;
for (final KettleQueryEntry queryEntry : getQueryEntries())
{
valid = queryEntry.isValidated();
if (!valid)
{
break;
}
}
if (valid == false && onConfirm == true)
{
int val = JOptionPane.showConfirmDialog(this,
Messages.getString("EmbeddedKettleDataSourceDialog.QueryErrorWarning"),
Messages.getString("EmbeddedKettleDataSourceDialog.QueryErrorTitle"), JOptionPane.OK_CANCEL_OPTION);
valid = (val == JOptionPane.OK_OPTION);
}
return valid && super.validateInputs(onConfirm);
}
public KettleDataFactory performConfiguration(DesignTimeContext context,
final KettleDataFactory dataFactory,
final String queryName) throws KettleException
{
configureFromDataFactory(dataFactory, queryName);
if ((dataFactory == null) || (!dataFactory.queriesAreHomogeneous()))
{
// allow caller to render the default dialog... we are done here
return super.performConfiguration(context, dataFactory, queryName);
}
else
{
try
{
refreshQueryUIComponents();
if (performEdit() == false)
{
return null;
}
}
catch (Exception e)
{
// attempt to fall back to the default dialog...
//TODO: LOG SOMETHING USEFUL HERE
return super.performConfiguration(context, dataFactory, queryName);
}
}
final KettleDataFactory kettleDataFactory = new KettleDataFactory();
kettleDataFactory.setMetadata(dataFactory.getMetaData());
for (final KettleQueryEntry queryEntry : getQueryEntries())
{
final KettleTransformationProducer producer = queryEntry.createProducer();
kettleDataFactory.setQuery(queryEntry.getName(), producer);
}
return kettleDataFactory;
}
protected EmbeddedKettleQueryEntry createNewQueryEntry(String queryName) throws KettleException
{
EmbeddedKettleQueryEntry entry =
EmbeddedKettleQueryEntry.createFromTemplate(queryName, datasourceId);
entry.addPropertyChangeListener("validated", new PreviewChangeListener());
return entry;
}
protected KettleQueryEntry createQueryEntry(String queryName, KettleTransformationProducer producer)
throws KettleException
{
if (datasourceId == null || producer instanceof EmbeddedKettleTransformationProducer == false)
{
return new FileKettleQueryEntry(queryName);
}
try
{
EmbeddedKettleTransformationProducer prod = (EmbeddedKettleTransformationProducer) producer;
EmbeddedKettleQueryEntry entry = EmbeddedKettleQueryEntry.createFromExisting(queryName, prod,
getDesignTimeContext().getDataFactoryContext());
entry.addPropertyChangeListener("validated", new PreviewChangeListener());
return entry;
}
catch (ReportDataFactoryException e)
{
throw new KettleException(e);
}
}
protected ListSelectionListener getQueryNameListener()
{
return new EmbeddedQueryNameListSelectionListener();
}
/**
* This method makes it possible to control any panel that gets rendered via XUL, without
* having to create hooks or listeners into the XUL dialog. The presence of a query object
* dictates whether the panel should be enabled or disabled.
*
* @param enable enable/disable the configuration panel
* @param c
*/
private void setPanelEnabled(boolean enable, Component c)
{
if (null == c)
{
return;
}
Container container = null;
if (c instanceof Container)
{
container = (Container) c;
}
if (container != null)
{
Component[] components = container.getComponents();
for (int i = 0; i < container.getComponentCount(); i++)
{
Component component = components[i];
setPanelEnabled(enable, component);
}
}
c.setEnabled(enable);
}
@Override
protected void clearComponents()
{
final EmbeddedKettleQueryEntry kettleQueryEntry = (EmbeddedKettleQueryEntry) getSelectedQuery();
kettleQueryEntry.clear();
super.clearComponents();
}
}