/*!
* 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.engine.classic.core.designtime;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.engine.classic.core.AbstractReportDefinition;
import org.pentaho.reporting.engine.classic.core.CompoundDataFactory;
import org.pentaho.reporting.engine.classic.core.DataFactory;
import org.pentaho.reporting.engine.classic.core.DataFactoryDesignTimeSupport;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.ParameterDataRow;
import org.pentaho.reporting.engine.classic.core.ReportDataFactoryException;
import org.pentaho.reporting.engine.classic.core.ReportProcessingException;
import org.pentaho.reporting.engine.classic.core.Section;
import org.pentaho.reporting.engine.classic.core.StaticDataRow;
import org.pentaho.reporting.engine.classic.core.cache.CachingDataFactory;
import org.pentaho.reporting.engine.classic.core.cache.IndexedTableModel;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.DesignTimeDataFactoryContext;
import org.pentaho.reporting.engine.classic.core.function.Expression;
import org.pentaho.reporting.engine.classic.core.parameters.ParameterDefinitionEntry;
import org.pentaho.reporting.engine.classic.core.sorting.SortConstraint;
import org.pentaho.reporting.engine.classic.core.sorting.SortOrderReportPreProcessor;
import org.pentaho.reporting.engine.classic.core.sorting.SortingDataFactory;
import org.pentaho.reporting.engine.classic.core.states.NoOpPerformanceMonitorContext;
import org.pentaho.reporting.engine.classic.core.states.QueryDataRowWrapper;
import org.pentaho.reporting.engine.classic.core.states.datarow.EmptyTableModel;
import org.pentaho.reporting.engine.classic.core.util.CloseableTableModel;
import org.pentaho.reporting.engine.classic.core.util.ReportParameterValues;
import org.pentaho.reporting.engine.classic.core.wizard.DataSchema;
import org.pentaho.reporting.engine.classic.core.wizard.DataSchemaCompiler;
import org.pentaho.reporting.engine.classic.core.wizard.DefaultDataAttributeContext;
import org.pentaho.reporting.engine.classic.core.wizard.DefaultDataSchema;
import org.pentaho.reporting.libraries.base.util.LinkedMap;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import java.util.Date;
import java.util.List;
public class DesignTimeDataSchemaModel extends AbstractDesignTimeDataSchemaModel {
private static final Log logger = LogFactory.getLog( DesignTimeDataSchemaModel.class );
private DataSchema dataSchema;
private OfflineTableModel offlineTableModel;
private Throwable dataFactoryException;
private final DesignTimeDataSchemaModelChangeTracker changeTracker;
public DesignTimeDataSchemaModel( final AbstractReportDefinition report ) {
this( (MasterReport) report.getMasterReport(), report );
}
public DesignTimeDataSchemaModel( final MasterReport masterReportElement, final AbstractReportDefinition report ) {
super( masterReportElement, report );
this.changeTracker = createChangeTracker();
}
protected DesignTimeDataSchemaModelChangeTracker createChangeTracker() {
return new DefaultDesignTimeDataSchemaModelChangeTracker( getParent() );
}
public AbstractReportDefinition getParent() {
return getReport();
}
public boolean isValid() {
ensureDataSchemaValid();
return dataFactoryException == null;
}
public DataSchema getDataSchema() {
ensureDataSchemaValid();
return dataSchema;
}
private void ensureDataSchemaValid() {
if ( dataSchema == null || changeTracker.isReportChanged() ) {
try {
this.dataFactoryException = null;
this.dataSchema = buildDataSchema();
} catch ( final Throwable e ) {
handleError( e );
this.dataFactoryException = e;
this.dataSchema = new DefaultDataSchema();
}
changeTracker.updateChangeTrackers();
}
}
protected void handleError( final Throwable e ) {
logger.debug( "Failure in DataSchema", e );
}
public Throwable getDataFactoryException() {
return dataFactoryException;
}
protected DataSchema buildDataSchema() throws ReportDataFactoryException {
this.dataFactoryException = null;
AbstractReportDefinition parent = getReport();
final ParameterDataRow parameterRow = computeParameterData();
final ParameterDefinitionEntry[] parameterDefinitions = computeParameterDefinitionEntries();
final Expression[] expressions = parent.getExpressions().getExpressions();
final DataSchemaCompiler dataSchemaCompiler =
new DataSchemaCompiler( getDataSchemaDefinition(), getDataAttributeContext(), getMasterReportElement()
.getResourceManager() );
try {
final CachingDataFactory dataFactory =
new CachingDataFactory( new SortingDataFactory( createDataFactory( parent ),
new NoOpPerformanceMonitorContext() ), true );
final MasterReport masterReport = getMasterReportElement();
dataFactory.initialize( new DesignTimeDataFactoryContext( masterReport ) );
try {
List<SortConstraint> sortConstraints = new SortOrderReportPreProcessor().computeSortConstraints( parent );
final TableModel reportData =
queryReportData( parent.getQuery(), parent.getQueryTimeout(), dataFactory, sortConstraints );
final DataSchema dataSchema =
dataSchemaCompiler.compile( reportData, expressions, parameterRow, parameterDefinitions, masterReport
.getReportEnvironment() );
// this.columnNames = collectColumnNames(reportData, parameterRow, expressions);
if ( reportData instanceof CloseableTableModel ) {
final CloseableTableModel ctm = (CloseableTableModel) reportData;
ctm.close();
}
return dataSchema;
} finally {
dataFactory.close();
}
} catch ( final ReportProcessingException e ) {
final TableModel reportData = new DefaultTableModel();
final DataSchema dataSchema =
dataSchemaCompiler.compile( reportData, expressions, parameterRow, parameterDefinitions,
getMasterReportElement().getReportEnvironment() );
this.dataFactoryException = e;
return dataSchema;
}
}
private CompoundDataFactory createDataFactory( AbstractReportDefinition reportDefinition )
throws ReportDataFactoryException {
final CompoundDataFactory cdf = new CompoundDataFactory();
while ( reportDefinition != null ) {
final DataFactory dataFactory = reportDefinition.getDataFactory();
if ( dataFactory != null ) {
cdf.add( dataFactory );
}
final Section parentSection = reportDefinition.getParentSection();
if ( parentSection == null ) {
reportDefinition = null;
} else {
reportDefinition = (AbstractReportDefinition) parentSection.getReportDefinition();
}
}
return CompoundDataFactory.normalize( cdf );
}
private TableModel queryReportData( final String query, final int queryTimeout, final DataFactory dataFactory,
final List<SortConstraint> sortConstraints ) throws ReportDataFactoryException {
if ( offlineTableModel == null || changeTracker.isReportQueryChanged() ) {
TableModel reportData = null;
try {
if ( query == null ) {
reportData = new EmptyTableModel();
} else if ( dataFactory instanceof DataFactoryDesignTimeSupport ) {
final DataFactoryDesignTimeSupport dts = (DataFactoryDesignTimeSupport) dataFactory;
reportData =
dts.queryDesignTimeStructure( query, new QueryDataRowWrapper( new StaticDataRow(), queryTimeout, 1,
sortConstraints ) );
} else {
reportData =
dataFactory.queryData( query, new QueryDataRowWrapper( new StaticDataRow(), queryTimeout, 1,
sortConstraints ) );
}
offlineTableModel = new OfflineTableModel( reportData, new DefaultDataAttributeContext() );
} finally {
if ( reportData instanceof CloseableTableModel ) {
final CloseableTableModel ctm = (CloseableTableModel) reportData;
ctm.close();
}
}
}
if ( offlineTableModel == null ) {
return new IndexedTableModel( new DefaultTableModel() );
}
return offlineTableModel;
}
@Deprecated
public boolean isSelectedDataSource( final DataFactory dataFactory, final String queryName ) {
return DesignTimeUtil.isSelectedDataSource( getReport(), dataFactory, queryName );
}
@Deprecated
public static LinkedMap computeParameterValueSet( final MasterReport report ) {
final LinkedMap retval = new LinkedMap();
retval.put( MasterReport.REPORT_DATE_PROPERTY, new Date() );
final ReportParameterValues reportParameterValues = report.getParameterValues();
final ParameterDefinitionEntry[] columnNames = report.getParameterDefinition().getParameterDefinitions();
for ( int i = 0; i < columnNames.length; i++ ) {
final ParameterDefinitionEntry parameter = columnNames[i];
final String columnName = parameter.getName();
if ( columnName == null ) {
continue;
}
retval.put( columnName, reportParameterValues.get( columnName ) );
}
return retval;
}
}