/*! * 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.designer.core.editor.parameters; import com.google.common.annotations.VisibleForTesting; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dialog; import java.awt.Dimension; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.lang.reflect.Array; import java.math.BigDecimal; import java.math.BigInteger; import java.sql.Time; import java.sql.Timestamp; import java.util.Arrays; import java.util.Date; import java.util.LinkedHashSet; import java.util.Objects; import java.util.TimeZone; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.JSpinner; import javax.swing.JSplitPane; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.SpinnerNumberModel; import javax.swing.event.DocumentEvent; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.table.TableModel; import javax.swing.tree.TreePath; import org.pentaho.reporting.designer.core.ReportDesignerContext; import org.pentaho.reporting.designer.core.editor.ReportDocumentContext; import org.pentaho.reporting.designer.core.settings.ui.ValidationMessage; import org.pentaho.reporting.designer.core.settings.ui.ValidationResult; import org.pentaho.reporting.designer.core.util.FormulaEditorDataModel; import org.pentaho.reporting.designer.core.util.FormulaEditorPanel; import org.pentaho.reporting.designer.core.util.exceptions.UncaughtExceptionsModel; import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot; import org.pentaho.reporting.engine.classic.core.CompoundDataFactory; import org.pentaho.reporting.engine.classic.core.DataFactory; import org.pentaho.reporting.engine.classic.core.DataRow; import org.pentaho.reporting.engine.classic.core.DefaultReportEnvironment; import org.pentaho.reporting.engine.classic.core.DefaultResourceBundleFactory; import org.pentaho.reporting.engine.classic.core.MasterReport; import org.pentaho.reporting.engine.classic.core.ReportDataFactoryException; import org.pentaho.reporting.engine.classic.core.ReportEnvironment; import org.pentaho.reporting.engine.classic.core.ReportEnvironmentDataRow; import org.pentaho.reporting.engine.classic.core.ReportProcessingException; import org.pentaho.reporting.engine.classic.core.ResourceBundleFactory; import org.pentaho.reporting.engine.classic.core.StaticDataRow; import org.pentaho.reporting.engine.classic.core.cache.CachingDataFactory; import org.pentaho.reporting.engine.classic.core.designtime.datafactory.DesignTimeDataFactoryContext; import org.pentaho.reporting.engine.classic.core.parameters.AbstractParameter; import org.pentaho.reporting.engine.classic.core.parameters.CompoundDataRow; import org.pentaho.reporting.engine.classic.core.parameters.DefaultListParameter; import org.pentaho.reporting.engine.classic.core.parameters.ListParameter; import org.pentaho.reporting.engine.classic.core.parameters.ParameterAttributeNames; import org.pentaho.reporting.engine.classic.core.parameters.ParameterContext; import org.pentaho.reporting.engine.classic.core.parameters.ParameterDefinitionEntry; import org.pentaho.reporting.engine.classic.core.parameters.PlainParameter; import org.pentaho.reporting.engine.classic.core.parameters.StaticListParameter; import org.pentaho.reporting.engine.classic.core.states.NoOpPerformanceMonitorContext; import org.pentaho.reporting.engine.classic.core.states.PerformanceMonitorContext; import org.pentaho.reporting.engine.classic.core.states.QueryDataRowWrapper; import org.pentaho.reporting.engine.classic.core.util.ReportParameterValues; import org.pentaho.reporting.libraries.base.config.Configuration; import org.pentaho.reporting.libraries.base.util.StringUtils; import org.pentaho.reporting.libraries.designtime.swing.CommonDialog; import org.pentaho.reporting.libraries.designtime.swing.KeyedComboBoxModel; import org.pentaho.reporting.libraries.designtime.swing.event.DocumentChangeHandler; import org.pentaho.reporting.libraries.docbundle.DocumentMetaData; import org.pentaho.reporting.libraries.docbundle.MemoryDocumentMetaData; import org.pentaho.reporting.libraries.resourceloader.ResourceKey; import org.pentaho.reporting.libraries.resourceloader.ResourceManager; import org.pentaho.reporting.libraries.xmlns.common.ParserUtil; /* * @author Ezequiel Cuellar */ public class ParameterDialog extends CommonDialog implements FormulaEditorDataModel { private static final ValidationMessage.Severity[] ALL_SEVERITIES = new ValidationMessage.Severity[] { ValidationMessage.Severity.WARN, ValidationMessage.Severity.ERROR }; private static final Class[] DEFAULT_CLASSES = { String.class, Boolean.class, Number.class, Date.class, java.sql.Date.class, Time.class, Timestamp.class, Double.class, Float.class, Integer.class, Long.class, Short.class, Byte.class, BigInteger.class, BigDecimal.class, TableModel.class, Object.class }; private ReportDesignerContext reportDesignerContext; private ProvisionDataSourcePanel provisionDataSourcePanel; private JTextField nameTextField; @VisibleForTesting JTextField labelTextField; private DefaultValueEditorPanel defaultValueTextField; @VisibleForTesting JTextField dataFormatField; private DataFactoryTreeModel availableDataSourcesModel; private JComboBox idComboBox; private JComboBox displayValueComboBox; private JComboBox valueTypeComboBox; private JCheckBox mandatoryCheckBox; private JCheckBox hiddenCheckBox; private JCheckBox strictValuesCheckBox; private JCheckBox autofillSelectionCheckBox; private JCheckBox reevaluateOnInvalidStrictParamCheckBox; private JLabel displayFormulaLabel; private FormulaEditorPanel postProcessingFormulaField; private FormulaEditorPanel displayFormulaField; private FormulaEditorPanel defaultValueFormulaField; @VisibleForTesting FormulaEditorPanel labelFormula; @VisibleForTesting FormulaEditorPanel dataFormatFormula; private JSpinner visibleItemsTextField; private JLabel visibleItemsLabel; private ComboBoxModel parameterTypeModel; private JTree availableDataSources; private StaticTextComboBoxModel queryComboBoxModel; private ParameterContext parameterContext; private JLabel displayValueLabel; private JComboBox timeZoneBox; private KeyedComboBoxModel<String, String> timeZoneModel; private JLabel timeZoneLabel; private String parameter; public ParameterDialog( final ReportDesignerContext context ) { this.reportDesignerContext = context; init(); } public ParameterDialog( final Dialog aParent, final ReportDesignerContext context ) { super( aParent ); this.reportDesignerContext = context; init(); } public ParameterDialog( final Frame aParent, final ReportDesignerContext context ) { super( aParent ); this.reportDesignerContext = context; init(); } protected void init() { provisionDataSourcePanel = new ProvisionDataSourcePanel(); provisionDataSourcePanel.setReportDesignerContext( reportDesignerContext ); parameterContext = new EditorParameterContext(); setModal( true ); availableDataSourcesModel = provisionDataSourcePanel.getDataFactoryTreeModel(); availableDataSourcesModel.addTreeModelListener( new DataSetQueryUpdateHandler() ); provisionDataSourcePanel.getDataSourcesTree() .addTreeSelectionListener( new QuerySelectionHandler() ); availableDataSources = provisionDataSourcePanel.getDataSourcesTree(); defaultValueTextField = new DefaultValueEditorPanel(); dataFormatField = new JTextField(); final TypeSelectionHandler typeSelectionHandler = new TypeSelectionHandler( defaultValueTextField ); dataFormatField.getDocument().addDocumentListener( typeSelectionHandler ); nameTextField = new JTextField(); labelTextField = new JTextField(); mandatoryCheckBox = new JCheckBox( Messages.getString( "ParameterDialog.Mandatory" ) ); mandatoryCheckBox.setBorder( BorderFactory.createEmptyBorder( 3, 0, 0, 0 ) ); hiddenCheckBox = new JCheckBox( Messages.getString( "ParameterDialog.Hidden" ) ); hiddenCheckBox.setBorder( BorderFactory.createEmptyBorder( 3, 0, 0, 0 ) ); strictValuesCheckBox = new JCheckBox( Messages.getString( "ParameterDialog.StrictValues" ) ); strictValuesCheckBox.setBorder( BorderFactory.createEmptyBorder( 3, 0, 0, 0 ) ); reevaluateOnInvalidStrictParamCheckBox = new JCheckBox( Messages.getString( "ParameterDialog.ReevaluateOnInvalidStrictParam" ) ); reevaluateOnInvalidStrictParamCheckBox.setBorder( BorderFactory.createEmptyBorder( 3, 0, 0, 0 ) ); autofillSelectionCheckBox = new JCheckBox( Messages.getString( "ParameterDialog.AutofillSelection" ) ); autofillSelectionCheckBox.setBorder( BorderFactory.createEmptyBorder( 3, 0, 0, 0 ) ); parameterTypeModel = ParameterType.createParameterTypesModel(); parameterTypeModel.addListDataListener( new TypeListener() ); parameterTypeModel.addListDataListener( typeSelectionHandler ); timeZoneModel = new KeyedComboBoxModel<>(); timeZoneModel.setAllowOtherValue( true ); timeZoneModel.add( "utc", Messages.getString( "ParameterDialog.UseUniversalTime" ) ); timeZoneModel.add( "server", Messages.getString( "ParameterDialog.UseServerTimezone" ) ); timeZoneModel.add( "client", Messages.getString( "ParameterDialog.UseClientTimezone" ) ); final String[] timeZoneId = TimeZone.getAvailableIDs(); Arrays.sort( timeZoneId ); for ( int i = 0; i < timeZoneId.length; i++ ) { final String string = timeZoneId[ i ]; final TimeZone timeZone = TimeZone.getTimeZone( string ); timeZoneModel.add( timeZone.getID(), Messages.getString( "ParameterDialog.TimeZoneLabel", timeZone.getID(), timeZone.getDisplayName() ) ); } timeZoneModel.addListDataListener( typeSelectionHandler ); timeZoneBox = new JComboBox( timeZoneModel ); timeZoneLabel = new JLabel( Messages.getString( "ParameterDialog.TimeZone" ) ); queryComboBoxModel = new StaticTextComboBoxModel(); queryComboBoxModel.addListDataListener( new QuerySelectionHandler() ); idComboBox = new JComboBox(); idComboBox.setEditable( true ); displayValueLabel = new JLabel( Messages.getString( "ParameterDialog.DisplayName" ) ); displayValueComboBox = new JComboBox(); displayValueComboBox.setEditable( true ); valueTypeComboBox = new JComboBox( new DefaultComboBoxModel( DEFAULT_CLASSES ) ); valueTypeComboBox.setEditable( true ); valueTypeComboBox.setEditor( new ClassComboBoxEditor( true, DEFAULT_CLASSES ) ); valueTypeComboBox.setRenderer( new ClassListCellRenderer() ); valueTypeComboBox.getModel().addListDataListener( typeSelectionHandler ); visibleItemsLabel = new JLabel( Messages.getString( "ParameterDialog.VisibleItems" ) ); visibleItemsTextField = new JSpinner( new SpinnerNumberModel( 0, 0, 50000, 1 ) ); displayFormulaLabel = new JLabel( Messages.getString( "ParameterDialog.DisplayFormula" ) ); displayFormulaField = new FormulaEditorPanel(); displayFormulaField.setEditorDataModel( this ); displayFormulaField.setLimitFields( true ); postProcessingFormulaField = new FormulaEditorPanel(); postProcessingFormulaField.setEditorDataModel( this ); postProcessingFormulaField.setLimitFields( true ); defaultValueFormulaField = new FormulaEditorPanel(); defaultValueFormulaField.setEditorDataModel( this ); defaultValueFormulaField.setLimitFields( true ); labelFormula = new FormulaEditorPanel(); labelFormula.setEditorDataModel( this ); labelFormula.setLimitFields( true ); dataFormatFormula = new FormulaEditorPanel(); dataFormatFormula.setEditorDataModel( this ); dataFormatFormula.setLimitFields( true ); super.init(); timeZoneBox.setVisible( false ); timeZoneLabel.setVisible( false ); displayFormulaField.setVisible( false ); visibleItemsLabel.setVisible( false ); visibleItemsTextField.setVisible( false ); displayFormulaLabel.setVisible( false ); displayValueLabel.setVisible( false ); displayValueComboBox.setVisible( false ); strictValuesCheckBox.setVisible( false ); reevaluateOnInvalidStrictParamCheckBox.setVisible( false ); autofillSelectionCheckBox.setVisible( false ); } protected String getDialogId() { return "ReportDesigner.Core.Parameter"; // NON-NLS } @SuppressWarnings( "HardCodedStringLiteral" ) private TimeZone getSelectedTimeZone() { final Object selectedItem = timeZoneModel.getSelectedKey(); if ( selectedItem == null ) { return TimeZone.getDefault(); } if ( "server".equals( selectedItem ) || "client".equals( selectedItem ) ) { return TimeZone.getDefault(); } final String id = String.valueOf( selectedItem ); if ( "utc".equals( id ) ) { return TimeZone.getTimeZone( "UTC" ); } final TimeZone timeZone = TimeZone.getTimeZone( id ); if ( "GMT".equals( timeZone.getID() ) && "GMT".equals( id ) == false ) { // Handle timezones that are not understood by the current JVM. return TimeZone.getDefault(); } return timeZone; } protected Component createContentPane() { final JSplitPane mainPanel = new JSplitPane(); mainPanel.setOrientation( JSplitPane.HORIZONTAL_SPLIT ); mainPanel.setLeftComponent( provisionDataSourcePanel ); mainPanel.setRightComponent( createDetailsPanel() ); mainPanel.setDividerLocation( 300 ); return mainPanel; } private JPanel createDetailsPanel() { final JComboBox queryBox = new JComboBox( queryComboBoxModel ); queryBox.setEditable( true ); final JPanel detailsPanel = new JPanel( new GridBagLayout() ); detailsPanel.setBorder( BorderFactory.createEmptyBorder( 30, 5, 10, 10 ) ); final GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets( 5, 5, 0, 0 ); gbc.anchor = GridBagConstraints.LINE_START; gbc.gridy = 0; gbc.gridx = 0; detailsPanel.add( new JLabel( Messages.getString( "ParameterDialog.Name" ) ), gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1.0; gbc.gridx = 1; detailsPanel.add( nameTextField, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0.0; gbc.gridy = 1; gbc.gridx = 0; detailsPanel.add( new JLabel( Messages.getString( "ParameterDialog.Label" ) ), gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( labelTextField, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0.0; gbc.gridy = 2; gbc.gridx = 0; detailsPanel.add( new JLabel( Messages.getString( "ParameterDialog.LabelFormula" ) ), gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( labelFormula, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 3; gbc.gridx = 0; detailsPanel.add( new JLabel( Messages.getString( "ParameterDialog.ValueType" ) ), gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( valueTypeComboBox, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 4; gbc.gridx = 0; detailsPanel.add( new JLabel( Messages.getString( "ParameterDialog.DataFormat" ) ), gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( dataFormatField, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 5; gbc.gridx = 0; detailsPanel.add( new JLabel( Messages.getString( "ParameterDialog.DataFormatFormula" ) ), gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( dataFormatFormula, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 6; gbc.gridx = 0; detailsPanel.add( timeZoneLabel, gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( timeZoneBox, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 7; gbc.gridx = 0; detailsPanel.add( new JLabel( Messages.getString( "ParameterDialog.DefaultValue" ) ), gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( defaultValueTextField, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 8; gbc.gridx = 0; detailsPanel.add( new JLabel( Messages.getString( "ParameterDialog.DefaultValueFormula" ) ), gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( defaultValueFormulaField, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 9; gbc.gridx = 0; detailsPanel.add( new JLabel( Messages.getString( "ParameterDialog.PostProcessingFormula" ) ), gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( postProcessingFormulaField, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 10; gbc.gridx = 1; detailsPanel.add( mandatoryCheckBox, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 11; gbc.gridx = 1; detailsPanel.add( hiddenCheckBox, gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridy = 12; gbc.gridx = 0; detailsPanel.add( createPromptPanel(), gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 13; gbc.gridx = 0; detailsPanel.add( new JLabel( Messages.getString( "ParameterDialog.Type" ) ), gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( new JComboBox( parameterTypeModel ), gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 14; gbc.gridx = 0; detailsPanel.add( new JLabel( Messages.getString( "ParameterDialog.Query" ) ), gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( queryBox, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 15; gbc.gridx = 0; detailsPanel.add( new JLabel( Messages.getString( "ParameterDialog.Id" ) ), gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( idComboBox, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 16; gbc.gridx = 0; detailsPanel.add( displayValueLabel, gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( displayValueComboBox, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 17; gbc.gridx = 0; detailsPanel.add( displayFormulaLabel, gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( displayFormulaField, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 18; gbc.gridx = 0; detailsPanel.add( visibleItemsLabel, gbc ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 1; detailsPanel.add( visibleItemsTextField, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 19; gbc.gridx = 1; detailsPanel.add( strictValuesCheckBox, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 20; gbc.gridx = 1; detailsPanel.add( reevaluateOnInvalidStrictParamCheckBox, gbc ); gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.gridy = 21; gbc.gridx = 1; detailsPanel.add( autofillSelectionCheckBox, gbc ); final JPanel theDetailsLayoutPanel = new JPanel( new BorderLayout() ); theDetailsLayoutPanel.add( detailsPanel, BorderLayout.NORTH ); return theDetailsLayoutPanel; } private Box createPromptPanel() { final Box pane = Box.createHorizontalBox(); pane.setBorder( BorderFactory.createEmptyBorder( 15, 0, 10, 0 ) ); final JLabel promptLabel = new JLabel( Messages.getString( "ParameterDialog.Prompt" ) ); pane.add( promptLabel ); pane.add( Box.createRigidArea( new Dimension( 10, 0 ) ) ); final JSeparator horizontalSeparator = new JSeparator(); horizontalSeparator.setAlignmentY( TOP_ALIGNMENT ); pane.add( horizontalSeparator ); return pane; } @VisibleForTesting void updateFromParameter( final ParameterDefinitionEntry p ) { if ( p == null ) { dataFormatField.setText( null ); labelTextField.setText( null ); nameTextField.setText( null ); defaultValueTextField.setValue( null, String.class ); visibleItemsTextField.setValue( 0 ); parameterTypeModel.setSelectedItem( null ); availableDataSources.clearSelection(); displayValueComboBox.setSelectedItem( null ); valueTypeComboBox.setSelectedItem( String.class ); mandatoryCheckBox.setSelected( false ); hiddenCheckBox.setSelected( false ); postProcessingFormulaField.setFormula( null ); displayFormulaField.setFormula( null ); strictValuesCheckBox.setSelected( true ); timeZoneBox.setSelectedItem( null ); autofillSelectionCheckBox.setSelected( false ); reevaluateOnInvalidStrictParamCheckBox.setSelected( false ); setSelectedQuery( null ); return; } final boolean multiSelection; if ( p instanceof DefaultListParameter ) { final DefaultListParameter parameter = (DefaultListParameter) p; final String queryName = parameter.getQueryName(); final DataFactory factoryForQuery = findDataFactoryForQuery( queryName ); if ( factoryForQuery != null ) { final int idx = availableDataSourcesModel.indexOf( factoryForQuery ); availableDataSources.setSelectionPath( new TreePath( new Object[] { availableDataSourcesModel.getRoot(), availableDataSourcesModel.get( idx ), queryName } ) ); } else { setSelectedQuery( queryName ); } autofillSelectionCheckBox.setSelected( "true".equals( parameter.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.AUTOFILL_SELECTION, parameterContext ) ) ); reevaluateOnInvalidStrictParamCheckBox.setSelected( "true".equals( parameter.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.RE_EVALUATE_ON_FAILED_VALUES, parameterContext ) ) ); strictValuesCheckBox.setSelected( parameter.isStrictValueCheck() ); displayValueComboBox.setSelectedItem( parameter.getTextColumn() ); idComboBox.setSelectedItem( parameter.getKeyColumn() ); final int visibleItems = ParserUtil.parseInt( parameter.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.VISIBLE_ITEMS ), 0 ); visibleItemsTextField.setValue( visibleItems ); } else { autofillSelectionCheckBox.setSelected( false ); reevaluateOnInvalidStrictParamCheckBox.setSelected( false ); strictValuesCheckBox.setSelected( true ); } if ( p instanceof ListParameter ) { multiSelection = ( (ListParameter) p ).isAllowMultiSelection(); } else { multiSelection = false; } final Class theType = p.getValueType(); valueTypeComboBox.setSelectedItem( multiSelection ? theType.getComponentType() : theType ); nameTextField.setText( p.getName() ); // do not show formula in label text. // if label will be empty but label formula is not, // we will set formula text to label. final String labelText = p.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.LABEL, parameterContext ); final String labelFormulaText = p.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.LABEL_FORMULA, parameterContext ); labelTextField.setText( Objects.equals( labelText, labelFormulaText ) ? "" : labelText ); labelFormula.setFormula( labelFormulaText ); // same approach for data format text. final String dataFormatText = p.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DATA_FORMAT, parameterContext ); final String dataFormatFormulaText = p.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DATA_FORMAT_FORMULA, parameterContext ); dataFormatField.setText( Objects.equals( dataFormatText, dataFormatFormulaText ) ? "" : dataFormatText ); dataFormatFormula.setFormula( dataFormatFormulaText ); mandatoryCheckBox.setSelected( p.isMandatory() ); postProcessingFormulaField.setFormula( p.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.POST_PROCESSOR_FORMULA, parameterContext ) ); displayFormulaField.setFormula( p.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DISPLAY_VALUE_FORMULA, parameterContext ) ); final String hiddenValue = p.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.HIDDEN, parameterContext ); if ( hiddenValue != null ) { hiddenCheckBox.setSelected( hiddenValue.equals( "true" ) ); } if ( p instanceof AbstractParameter ) { final AbstractParameter parameter = (AbstractParameter) p; defaultValueTextField.setValue( parameter.getDefaultValue(), parameter.getValueType() ); } else { defaultValueTextField.setValue( null, p.getValueType() ); } defaultValueFormulaField.setFormula( p.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DEFAULT_VALUE_FORMULA, parameterContext ) ); timeZoneModel.setSelectedKey( p.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.TIMEZONE, parameterContext ) ); final String type = p.getParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.TYPE, parameterContext ); if ( type != null ) { final int size = parameterTypeModel.getSize(); for ( int i = 0; i < size; i++ ) { final ParameterType typeEntry = (ParameterType) parameterTypeModel.getElementAt( i ); if ( typeEntry == null ) { continue; } if ( typeEntry.isMultiSelection() == multiSelection ) { if ( type.equals( typeEntry.getInternalName() ) ) { parameterTypeModel.setSelectedItem( typeEntry ); break; } } } } else { parameterTypeModel.setSelectedItem( null ); } } private String getSelectedQuery() { return (String) queryComboBoxModel.getSelectedItem(); } private void setSelectedQuery( final String query ) { queryComboBoxModel.setSelectedItem( query ); } private ParameterDefinitionEntry createParameterResult() { final String query = getSelectedQuery(); final String name = nameTextField.getText(); final String label = labelTextField.getText(); final Object rawDefaultValue = defaultValueTextField.getValue(); final String dataFormat = dataFormatField.getText(); final boolean isMandatory = mandatoryCheckBox.isSelected(); final ParameterType type = (ParameterType) parameterTypeModel.getSelectedItem(); if ( query == null ) { return createQuerylessParameter( name, label, rawDefaultValue, dataFormat, isMandatory, type ); } final String keyColumn = (String) idComboBox.getSelectedItem(); final boolean isMultiSelect; final boolean hasVisibleItems; final boolean queryIsOptional; final String layout; final String typeName; if ( type != null ) { isMultiSelect = type.isMultiSelection(); layout = type.getLayout(); typeName = type.getInternalName(); queryIsOptional = type.isQueryOptional(); hasVisibleItems = type.isHasVisibleItems(); } else { isMultiSelect = false; layout = null; typeName = null; queryIsOptional = true; hasVisibleItems = false; } final String textColumn; if ( queryIsOptional ) { textColumn = keyColumn; } else { textColumn = (String) displayValueComboBox.getSelectedItem(); } final Class selectedType = (Class) valueTypeComboBox.getSelectedItem(); final Class valueType = ( isMultiSelect ? Array.newInstance( selectedType, 0 ).getClass() : selectedType ); final DefaultListParameter parameter = new DefaultListParameter( query, keyColumn, textColumn, name, isMultiSelect, strictValuesCheckBox.isSelected(), valueType ); parameter .setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.LAYOUT, layout ); parameter .setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.TYPE, typeName ); parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.RE_EVALUATE_ON_FAILED_VALUES, String.valueOf( reevaluateOnInvalidStrictParamCheckBox.isSelected() ) ); parameter .setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.AUTOFILL_SELECTION, String.valueOf( autofillSelectionCheckBox.isSelected() ) ); if ( !StringUtils.isEmpty( label ) ) { parameter .setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.LABEL, label ); } else if ( !StringUtils.isEmpty( labelFormula.getFormula() ) ) { parameter .setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.LABEL, labelFormula.getFormula() ); } parameter.setMandatory( isMandatory ); parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.HIDDEN, String.valueOf( hiddenCheckBox.isSelected() ) ); parameter.setDefaultValue( rawDefaultValue ); if ( hasVisibleItems ) { final Number visibleItemsInput = (Number) visibleItemsTextField.getValue(); if ( visibleItemsInput != null && visibleItemsInput.intValue() > 0 ) { parameter .setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.VISIBLE_ITEMS, String.valueOf( visibleItemsInput ) ); } } if ( !StringUtils.isEmpty( dataFormat ) ) { parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DATA_FORMAT, dataFormat ); } else if ( !StringUtils.isEmpty( dataFormatFormula.getFormula() ) ) { // copy formula to a data format to have data format applied. parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DATA_FORMAT, dataFormatFormula.getFormula() ); } if ( queryIsOptional == false ) { parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DISPLAY_VALUE_FORMULA, displayFormulaField.getFormula() ); } parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DEFAULT_VALUE_FORMULA, defaultValueFormulaField.getFormula() ); parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.POST_PROCESSOR_FORMULA, postProcessingFormulaField.getFormula() ); parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.TIMEZONE, timeZoneModel.getSelectedKey() ); if ( !StringUtils.isEmpty( labelFormula.getFormula() ) ) { parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.LABEL_FORMULA, labelFormula.getFormula() ); } if ( !StringUtils.isEmpty( dataFormatFormula.getFormula() ) ) { parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DATA_FORMAT_FORMULA, dataFormatFormula.getFormula() ); } return parameter; } @VisibleForTesting ParameterDefinitionEntry createQuerylessParameter( final String name, final String label, final Object rawDefaultValue, final String dataFormat, final boolean mandatory, final ParameterType type ) { final Class selectedType = (Class) valueTypeComboBox.getSelectedItem(); final AbstractParameter parameter; if ( type == null || !type.isMultiSelection() ) { // single value parameter parameter = new PlainParameter( name ); parameter.setValueType( selectedType ); } else { // multi-value parameter final Class valueType = Array.newInstance( selectedType, 0 ).getClass(); parameter = new StaticListParameter( name, true, false, valueType ); } if ( type != null ) { parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.TYPE, type.getInternalName() ); } if ( !StringUtils.isEmpty( label ) ) { parameter .setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.LABEL, label ); } else if ( !StringUtils.isEmpty( labelFormula.getFormula() ) ) { parameter .setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.LABEL, labelFormula.getFormula() ); } parameter.setDefaultValue( rawDefaultValue ); parameter.setMandatory( mandatory ); parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.HIDDEN, String.valueOf( hiddenCheckBox.isSelected() ) ); if ( !StringUtils.isEmpty( dataFormat ) ) { parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DATA_FORMAT, dataFormat ); } else if ( !StringUtils.isEmpty( dataFormatFormula.getFormula() ) ) { // copy formula to a data format to have data format applied. parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DATA_FORMAT, dataFormatFormula.getFormula() ); } parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DEFAULT_VALUE_FORMULA, defaultValueFormulaField.getFormula() ); parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.POST_PROCESSOR_FORMULA, postProcessingFormulaField.getFormula() ); parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.TIMEZONE, timeZoneModel.getSelectedKey() ); if ( !StringUtils.isEmpty( labelFormula.getFormula() ) ) { parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.LABEL_FORMULA, labelFormula.getFormula() ); } if ( !StringUtils.isEmpty( dataFormatFormula.getFormula() ) ) { parameter.setParameterAttribute( ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.DATA_FORMAT_FORMULA, dataFormatFormula.getFormula() ); } return parameter; } private ParameterType getSelectedParameterType() { return (ParameterType) parameterTypeModel.getSelectedItem(); } private DataFactory findDataFactoryForQuery( final String query ) { if ( query == null ) { return null; } final QueryDataRowWrapper dataRow = new QueryDataRowWrapper( new ReportParameterValues(), 1, 0 ); final int size = availableDataSourcesModel.size(); for ( int i = 0; i < size; i++ ) { final DataFactoryWrapper factoryWrapper = availableDataSourcesModel.get( i ); if ( factoryWrapper.isRemoved() ) { continue; } final DataFactory factory = factoryWrapper.getEditedDataFactory(); if ( factory.isQueryExecutable( query, dataRow ) ) { return factory; } } return null; } public ParameterEditResult performEditParameter( final ReportDesignerContext context, final MasterReport masterReport, final ParameterDefinitionEntry parameterDefinitionEntry ) { if ( context == null ) { throw new NullPointerException(); } if ( parameterDefinitionEntry == null ) { setTitle( Messages.getString( "ParameterDialog.Title.Add" ) ); parameter = null; } else { setTitle( Messages.getString( "ParameterDialog.Title.Edit" ) ); parameter = parameterDefinitionEntry.getName(); } try { reportDesignerContext = context; displayFormulaField.setReportDesignerContext( context ); defaultValueFormulaField.setReportDesignerContext( context ); postProcessingFormulaField.setReportDesignerContext( context ); availableDataSourcesModel.importFromReport( (CompoundDataFactory) masterReport.getDataFactory() ); // Expand all the nodes provisionDataSourcePanel.expandAllNodes(); updateFromParameter( parameterDefinitionEntry ); if ( performEdit() ) { return new ParameterEditResult( availableDataSourcesModel.toArray(), createParameterResult() ); } return null; } finally { reportDesignerContext = null; displayFormulaField.setReportDesignerContext( null ); postProcessingFormulaField.setReportDesignerContext( null ); defaultValueFormulaField.setReportDesignerContext( null ); } } public String[] getDataFields() { final String queryName = getSelectedQuery(); if ( queryName == null ) { return new String[ 0 ]; } final DataFactory rawDataFactory = findDataFactoryForQuery( queryName ); if ( rawDataFactory == null ) { return new String[ 0 ]; } final DataFactory dataFactory = new CachingDataFactory( rawDataFactory, true ); try { final ReportDocumentContext activeContext = reportDesignerContext.getActiveContext(); if ( activeContext != null ) { final MasterReport reportDefinition = activeContext.getContextRoot(); dataFactory.initialize( new DesignTimeDataFactoryContext( reportDefinition ) ); } final TableModel tableModel = dataFactory.queryData( queryName, new QueryDataRowWrapper( new ReportParameterValues(), 1, 0 ) ); final int colCount = tableModel.getColumnCount(); final String[] cols = new String[ colCount ]; for ( int i = 0; i < colCount; i++ ) { cols[ i ] = tableModel.getColumnName( i ); } return cols; } catch ( ReportProcessingException aExc ) { UncaughtExceptionsModel.getInstance().addException( aExc ); return new String[ 0 ]; } finally { dataFactory.close(); } } public String getParameter() { return parameter; } @Override protected boolean validateInputs( boolean onConfirm ) { final ValidationResult validationResult = this.validate( new ValidationResult() ); final ValidationMessage[] validationMessages = validationResult.getValidationMessages( ALL_SEVERITIES ); if ( validationMessages.length == 0 ) { return true; } final StringBuilder messages = new StringBuilder( 100 ); for ( final ValidationMessage validationMessage : validationMessages ) { messages.append( validationMessage.getMessage() ); messages.append( '\n' ); } JOptionPane.showMessageDialog( ParameterDialog.this, messages, Messages.getString( "ParameterDialog.ErrorTitle" ), JOptionPane.WARNING_MESSAGE ); return false; } private ValidationResult validate( ValidationResult validationResult ) { if ( StringUtils.isEmpty( this.nameTextField.getText() ) ) { final String nameCaption = Messages.getString( "ParameterDialog.Name" ); validationResult.addValidationMessage( new ValidationMessage( ValidationMessage.Severity.ERROR, Messages .getString( "ParameterDialog.ValueMustBeSetMessage", nameCaption ) ) ); } return validationResult; } public static class ParameterEditResult { private DataFactoryWrapper[] wrappers; private ParameterDefinitionEntry parameter; public ParameterEditResult( final DataFactoryWrapper[] wrappers, final ParameterDefinitionEntry entries ) { this.wrappers = wrappers; this.parameter = entries; } public DataFactoryWrapper[] getWrappers() { return wrappers; } public ParameterDefinitionEntry getParameter() { return parameter; } } private class TypeListener implements ListDataListener { public void intervalAdded( final ListDataEvent e ) { } public void intervalRemoved( final ListDataEvent e ) { } public void contentsChanged( final ListDataEvent e ) { final ParameterType type = (ParameterType) parameterTypeModel.getSelectedItem(); final boolean visible = ( type != null ) && type.isHasVisibleItems(); visibleItemsTextField.setVisible( visible ); visibleItemsLabel.setVisible( visible ); final boolean displayFormulaVisible = ( type != null ) && type.isQueryOptional() == false; displayFormulaField.setVisible( displayFormulaVisible ); displayFormulaLabel.setVisible( displayFormulaVisible ); displayValueLabel.setVisible( displayFormulaVisible ); displayValueComboBox.setVisible( displayFormulaVisible ); final String selectedQuery = (String) queryComboBoxModel.getSelectedItem(); final boolean querySelected = StringUtils.isEmpty( selectedQuery, false ) == false; strictValuesCheckBox.setVisible( querySelected ); reevaluateOnInvalidStrictParamCheckBox.setVisible( querySelected ); autofillSelectionCheckBox.setVisible( querySelected ); } } private class DataSetQueryUpdateHandler implements TreeModelListener { private DataSetQueryUpdateHandler() { } /** * <p>Invoked after a node (or a set of siblings) has changed in some way. The node(s) have not changed locations in * the tree or altered their children arrays, but other attributes have changed and may affect presentation. * Example: the name of a file has changed, but it is in the same location in the file system.</p> <p>To indicate * the root has changed, childIndices and children will be null. </p> <p/> <p>Use <code>e.getPath()</code> to get * the parent of the changed node(s). <code>e.getChildIndices()</code> returns the index(es) of the changed * node(s).</p> */ public void treeNodesChanged( final TreeModelEvent e ) { valueChanged(); } /** * <p>Invoked after nodes have been inserted into the tree.</p> <p/> <p>Use <code>e.getPath()</code> to get the * parent of the new node(s). <code>e.getChildIndices()</code> returns the index(es) of the new node(s) in ascending * order.</p> */ public void treeNodesInserted( final TreeModelEvent e ) { valueChanged(); } /** * <p>Invoked after nodes have been removed from the tree. Note that if a subtree is removed from the tree, this * method may only be invoked once for the root of the removed subtree, not once for each individual set of siblings * removed.</p> <p/> <p>Use <code>e.getPath()</code> to get the former parent of the deleted node(s). * <code>e.getChildIndices()</code> returns, in ascending order, the index(es) the node(s) had before being * deleted.</p> */ public void treeNodesRemoved( final TreeModelEvent e ) { valueChanged(); } /** * <p>Invoked after the tree has drastically changed structure from a given node down. If the path returned by * e.getPath() is of length one and the first element does not identify the current root node the first element * should become the new root of the tree.<p> <p/> <p>Use <code>e.getPath()</code> to get the path to the node. * <code>e.getChildIndices()</code> returns null.</p> */ public void treeStructureChanged( final TreeModelEvent e ) { valueChanged(); } private void valueChanged() { final int count = availableDataSourcesModel.size(); final LinkedHashSet<String> set = new LinkedHashSet<>(); for ( int i = 0; i < count; i++ ) { final DataFactoryWrapper factoryWrapper = availableDataSourcesModel.get( i ); if ( factoryWrapper.isRemoved() ) { continue; } final String[] strings = factoryWrapper.getEditedDataFactory().getQueryNames(); set.addAll( Arrays.asList( strings ) ); } queryComboBoxModel.setValues( set.toArray( new String[ set.size() ] ) ); final TreePath selectionPath = availableDataSources.getSelectionPath(); if ( selectionPath == null ) { setSelectedQuery( null ); idComboBox.setModel( new DefaultComboBoxModel() ); displayValueComboBox.setModel( new DefaultComboBoxModel() ); return; } final Object maybeQuery = selectionPath.getLastPathComponent(); if ( maybeQuery instanceof String ) { setSelectedQuery( (String) maybeQuery ); } } } private class QuerySelectionHandler implements ListDataListener, TreeSelectionListener { private QuerySelectionHandler() { } /** * Called whenever the value of the selection changes. * * @param e the event that characterizes the change. */ public void valueChanged( final TreeSelectionEvent e ) { if ( e.getPath() == null ) { return; } final Object o = e.getPath().getLastPathComponent(); if ( o instanceof String ) { queryComboBoxModel.setSelectedItem( o ); } } public void intervalAdded( final ListDataEvent e ) { } public void intervalRemoved( final ListDataEvent e ) { } public void contentsChanged( final ListDataEvent e ) { final String[] cols = getDataFields(); idComboBox.setModel( new DefaultComboBoxModel( cols ) ); displayValueComboBox.setModel( new DefaultComboBoxModel( cols ) ); final String selectedQuery = (String) queryComboBoxModel.getSelectedItem(); final boolean querySelected = StringUtils.isEmpty( selectedQuery, false ) == false; strictValuesCheckBox.setVisible( querySelected ); reevaluateOnInvalidStrictParamCheckBox.setVisible( querySelected ); autofillSelectionCheckBox.setVisible( querySelected ); } } private class EditorParameterContext implements ParameterContext { private ReportEnvironment defaultEnvironment; private DocumentMetaData defaultDocumentMetaData; private DataRow dataRow; private ResourceBundleFactory resourceBundleFactory; private ResourceManager resourceManager; private EditorParameterContext() { resourceManager = new ResourceManager(); resourceBundleFactory = new DefaultResourceBundleFactory(); defaultEnvironment = new DefaultReportEnvironment( ClassicEngineBoot.getInstance().getGlobalConfig() ); defaultDocumentMetaData = new MemoryDocumentMetaData(); final ReportEnvironmentDataRow envDataRow = new ReportEnvironmentDataRow( defaultEnvironment ); dataRow = new CompoundDataRow( envDataRow, new StaticDataRow() ); } public PerformanceMonitorContext getPerformanceMonitorContext() { return new NoOpPerformanceMonitorContext(); } public DataRow getParameterData() { return dataRow; } public DataFactory getDataFactory() { return provisionDataSourcePanel.getSelectedDataSource(); } public ResourceManager getResourceManager() { if ( reportDesignerContext == null ) { return resourceManager; } final ReportDocumentContext activeContext = reportDesignerContext.getActiveContext(); if ( activeContext == null ) { return resourceManager; } return activeContext.getContextRoot().getResourceManager(); } public ResourceBundleFactory getResourceBundleFactory() { if ( reportDesignerContext == null ) { return resourceBundleFactory; } final ReportDocumentContext activeContext = reportDesignerContext.getActiveContext(); if ( activeContext == null ) { return resourceBundleFactory; } final MasterReport report = activeContext.getContextRoot(); return MasterReport .computeAndInitResourceBundleFactory( report.getResourceBundleFactory(), report.getReportEnvironment() ); } public Configuration getConfiguration() { if ( reportDesignerContext == null ) { return ClassicEngineBoot.getInstance().getGlobalConfig(); } final ReportDocumentContext activeContext = reportDesignerContext.getActiveContext(); if ( activeContext == null ) { return ClassicEngineBoot.getInstance().getGlobalConfig(); } return activeContext.getContextRoot().getConfiguration(); } public ResourceKey getContentBase() { if ( reportDesignerContext == null ) { return null; } final ReportDocumentContext activeContext = reportDesignerContext.getActiveContext(); if ( activeContext == null ) { return null; } return activeContext.getContextRoot().getContentBase(); } /** * the document metadata of the report. Can be null, if the report does not have a bundle associated or if this * context is not part of a report-processing. * * @return the document metadata. */ public DocumentMetaData getDocumentMetaData() { if ( reportDesignerContext == null ) { return defaultDocumentMetaData; } final ReportDocumentContext activeContext = reportDesignerContext.getActiveContext(); if ( activeContext == null ) { return defaultDocumentMetaData; } return activeContext.getContextRoot().getBundle().getMetaData(); } public ReportEnvironment getReportEnvironment() { if ( reportDesignerContext == null ) { return defaultEnvironment; } final ReportDocumentContext activeContext = reportDesignerContext.getActiveContext(); if ( activeContext == null ) { return defaultEnvironment; } return activeContext.getContextRoot().getReportEnvironment(); } public void close() throws ReportDataFactoryException { } } private class TypeSelectionHandler extends DocumentChangeHandler implements ListDataListener { private DefaultValueEditorPanel valueEditorPanel; private TypeSelectionHandler( final DefaultValueEditorPanel valueEditorPanel ) { this.valueEditorPanel = valueEditorPanel; } /** * Sent after the indices in the index0,index1 interval have been inserted in the data model. The new interval * includes both index0 and index1. * * @param e a <code>ListDataEvent</code> encapsulating the event information */ public void intervalAdded( final ListDataEvent e ) { // ignorable, model is static } /** * Sent after the indices in the index0,index1 interval have been removed from the data model. The interval * includes both index0 and index1. * * @param e a <code>ListDataEvent</code> encapsulating the event information */ public void intervalRemoved( final ListDataEvent e ) { // ignorable, model is static } /** * Sent when the contents of the list has changed in a way that's too complex to characterize with the previous * methods. For example, this is sent when an item has been replaced. Index0 and index1 bracket the change. * * @param event a <code>ListDataEvent</code> encapsulating the event information */ public void contentsChanged( final ListDataEvent event ) { final Object o = valueTypeComboBox.getSelectedItem(); if ( o instanceof Class == false ) { timeZoneLabel.setVisible( false ); timeZoneBox.setVisible( false ); valueEditorPanel.setValueType( String.class, null, TimeZone.getDefault() ); return; } final Class selectedClass = (Class) o; final ParameterType parameterType = getSelectedParameterType(); final Class type; if ( parameterType == null || parameterType.isMultiSelection() == false ) { type = selectedClass; } else { type = Array.newInstance( selectedClass, 0 ).getClass(); } timeZoneLabel.setVisible( Date.class.isAssignableFrom( selectedClass ) ); timeZoneBox.setVisible( Date.class.isAssignableFrom( selectedClass ) ); valueEditorPanel.setValueType( type, dataFormatField.getText(), getSelectedTimeZone() ); } protected void handleChange( final DocumentEvent e ) { contentsChanged( null ); } } }