http://dev.eclipse.org/viewcvs/viewvc.cgi/source/org.eclipse.birt.report.viewer/birt/WEB-INF/classes/org/eclipse/birt/report/services/ReportEngineService.java?view=co&revision=1.41&root=BIRT_Project
http://www.eclipse.org/birt/phoenix/deploy/reportEngineAPI.php
/************************************************************************************* * Copyright (c) 2004 Actuate Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Actuate Corporation - Initial implementation. ************************************************************************************/ package org.eclipse.birt.report.services; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.logging.Level; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.xml.namespace.QName; import org.apache.axis.AxisFault; import org.eclipse.birt.core.data.DataType; import org.eclipse.birt.core.data.DataTypeUtil; import org.eclipse.birt.core.exception.BirtException; import org.eclipse.birt.core.framework.IPlatformContext; import org.eclipse.birt.core.framework.PlatformServletContext; import org.eclipse.birt.data.engine.api.DataEngine; import org.eclipse.birt.data.engine.api.IResultMetaData; import org.eclipse.birt.report.engine.api.EngineConfig; import org.eclipse.birt.report.engine.api.EngineConstants; import org.eclipse.birt.report.engine.api.EngineException; import org.eclipse.birt.report.engine.api.HTMLActionHandler; import org.eclipse.birt.report.engine.api.HTMLEmitterConfig; import org.eclipse.birt.report.engine.api.HTMLRenderContext; import org.eclipse.birt.report.engine.api.HTMLRenderOption; import org.eclipse.birt.report.engine.api.HTMLServerImageHandler; import org.eclipse.birt.report.engine.api.IDataExtractionTask; import org.eclipse.birt.report.engine.api.IDataIterator; import org.eclipse.birt.report.engine.api.IExtractionResults; import org.eclipse.birt.report.engine.api.IGetParameterDefinitionTask; import org.eclipse.birt.report.engine.api.IRenderTask; import org.eclipse.birt.report.engine.api.IReportDocument; import org.eclipse.birt.report.engine.api.IReportRunnable; import org.eclipse.birt.report.engine.api.IRunAndRenderTask; import org.eclipse.birt.report.engine.api.IRunTask; import org.eclipse.birt.report.engine.api.IScalarParameterDefn; import org.eclipse.birt.report.engine.api.PDFRenderContext; import org.eclipse.birt.report.engine.api.ReportEngine; import org.eclipse.birt.report.engine.api.ReportParameterConverter; import org.eclipse.birt.report.engine.api.impl.IResultSetItem; import org.eclipse.birt.report.engine.api.impl.ScalarParameterDefn; import org.eclipse.birt.report.engine.script.internal.ScriptExecutor; import org.eclipse.birt.report.model.api.ScalarParameterHandle; import org.eclipse.birt.report.model.api.elements.DesignChoiceConstants; import org.eclipse.birt.report.soapengine.IBirtConstants; import org.eclipse.birt.report.soapengine.api.Column; import org.eclipse.birt.report.soapengine.api.ResultSet; import org.eclipse.birt.report.viewer.utilities.ParameterAccessor; public class ReportEngineService { private static ReportEngineService instance; /** * Report engine instance. */ private ReportEngine engine = null; /** * Static engine config instance. */ private EngineConfig config = null; /** * Image directory for report images and charts. */ private String imageDirectory = null; /** * URL accesses images. */ private String imageBaseUrl = null; /** * Image handler instance. */ private HTMLServerImageHandler imageHandler = null; /** * Web app context path. */ private String contextPath = null; /** * Constructor. * * @param config */ public ReportEngineService( ServletConfig config ) { initEngineInstance( config ); ReportEngineService.instance = this; } /** * Get engine instance. * * @return */ synchronized public static ReportEngineService getInstance( ) { return instance; } /** * Get engine instance. * * @return engine instance */ synchronized private void initEngineInstance( ServletConfig servletConfig ) { System.setProperty( "RUN_UNDER_ECLIPSE", "false" ); //$NON-NLS-1$ //$NON-NLS-2$ if ( servletConfig == null ) { return; } config = new EngineConfig( ); // Register new image handler HTMLEmitterConfig emitterConfig = new HTMLEmitterConfig( ); emitterConfig.setActionHandler( new HTMLActionHandler( ) ); imageHandler = new HTMLServerImageHandler( ); emitterConfig.setImageHandler( imageHandler ); config.getEmitterConfigs( ).put( "html", emitterConfig ); //$NON-NLS-1$ // Prepare image directory. imageDirectory = servletConfig.getServletContext( ).getInitParameter( ParameterAccessor.INIT_PARAM_IMAGE_DIR ); if ( imageDirectory == null || imageDirectory.trim( ).length( ) <= 0 || ParameterAccessor.isRelativePath( imageDirectory ) ) { imageDirectory = servletConfig.getServletContext( ).getRealPath( "/report/images" ); //$NON-NLS-1$ } // Prepare image base url. imageBaseUrl = "/run?__imageID="; //$NON-NLS-1$ // Prepare log directory. String logDirectory = servletConfig.getServletContext( ).getInitParameter( ParameterAccessor.INIT_PARAM_LOG_DIR ); if ( logDirectory == null || logDirectory.trim( ).length( ) <= 0 || ParameterAccessor.isRelativePath( logDirectory ) ) { logDirectory = servletConfig.getServletContext( ).getRealPath( "/logs" ); //$NON-NLS-1$ } // Prepare log level. String logLevel = servletConfig.getServletContext( ).getInitParameter( ParameterAccessor.INIT_PARAM_LOG_LEVEL ); Level level = Level.OFF; if ( "SEVERE".equalsIgnoreCase( logLevel ) ) //$NON-NLS-1$ { level = Level.SEVERE; } else if ( "WARNING".equalsIgnoreCase( logLevel ) ) //$NON-NLS-1$ { level = Level.WARNING; } else if ( "INFO".equalsIgnoreCase( logLevel ) ) //$NON-NLS-1$ { level = Level.INFO; } else if ( "CONFIG".equalsIgnoreCase( logLevel ) ) //$NON-NLS-1$ { level = Level.CONFIG; } else if ( "FINE".equalsIgnoreCase( logLevel ) ) //$NON-NLS-1$ { level = Level.FINE; } else if ( "FINER".equalsIgnoreCase( logLevel ) ) //$NON-NLS-1$ { level = Level.FINER; } else if ( "FINEST".equalsIgnoreCase( logLevel ) ) //$NON-NLS-1$ { level = Level.FINEST; } else if ( "OFF".equalsIgnoreCase( logLevel ) ) //$NON-NLS-1$ { level = Level.OFF; } config.setLogConfig( logDirectory, level ); // Prepare ScriptLib location String scriptLibDir = servletConfig.getServletContext( ).getInitParameter( ParameterAccessor.INIT_PARAM_SCRIPTLIB_DIR ); if ( scriptLibDir == null || scriptLibDir.trim( ).length( ) <= 0 || ParameterAccessor.isRelativePath( scriptLibDir ) ) { scriptLibDir = servletConfig.getServletContext( ).getRealPath( "/scriptlib" ); //$NON-NLS-1$ } ArrayList jarFileList = new ArrayList(); if ( scriptLibDir != null ) { File dir = new File( scriptLibDir ); getAllJarFiles( dir, jarFileList ); } String scriptlibClassPath = ""; //$NON-NLS-1$ for ( int i=0; i0 && pageNumber < reportDocument.getPageCount( ); ByteArrayOutputStream out = new ByteArrayOutputStream( ); // Create render task. IRenderTask renderTask = engine.createRenderTask( reportDocument ); HashMap context = new HashMap( ); context.put( EngineConstants.APPCONTEXT_HTML_RENDER_CONTEXT, createHTMLrenderContext( svgFlag ) ); context.put( EngineConstants.APPCONTEXT_BIRT_VIEWER_HTTPSERVET_REQUEST, request ); context.put( EngineConstants.APPCONTEXT_CLASSLOADER_KEY, ReportEngineService.class.getClassLoader()); renderTask.setAppContext( context ); // Render option HTMLRenderOption setting = new HTMLRenderOption( ); setting.setOutputStream( out ); setting.setOutputFormat( IBirtConstants.RENDERFORMAT ); setting.setEmbeddable( true ); setting.setInstanceIDs( activeIds ); setting.setMasterPageContent( masterPage ); setting.setActionHandle( new ViewerHTMLActionHandler( reportDocument, pageNumber) ); renderTask.setRenderOption( setting ); renderTask.setLocale( locale ); // Render designated page. try { renderTask.render( pageNumber ); } catch ( BirtException e ) { AxisFault fault = new AxisFault( ); fault.setFaultCode( new QName( "ReportEngineService.renderReport( )" ) ); //$NON-NLS-1$ fault.setFaultString( e.getLocalizedMessage( ) ); throw fault; } catch ( Exception e ) { AxisFault fault = new AxisFault( ); fault.setFaultCode( new QName( "ReportEngineService.renderReport( )" ) ); //$NON-NLS-1$ fault.setFaultString( e.getLocalizedMessage( ) ); throw fault; } finally { renderTask.close( ); } return out; } /** * Get query result sets. * * @param document * @return * @throws RemoteException */ synchronized public ResultSet[] getResultSets( IReportDocument document ) throws RemoteException { assert document != null; ResultSet[] resultSetArray = null; IDataExtractionTask dataTask = engine.createDataExtractionTask( document ); try { List resultSets = dataTask.getResultSetList( ); if ( resultSets != null && resultSets.size( ) > 0 ) { resultSetArray = new ResultSet[resultSets.size( )]; for ( int k = 0; k < resultSets.size( ); k++ ) { resultSetArray[k] = new ResultSet( ); IResultSetItem resultSetItem = ( IResultSetItem ) resultSets.get( k ); assert resultSetItem != null; resultSetArray[k].setQueryName( resultSetItem.getResultSetName( ) ); IResultMetaData metaData = resultSetItem.getResultMetaData( ); assert metaData != null; Column[] columnArray = new Column[metaData.getColumnCount( )]; for ( int i = 0; i < metaData.getColumnCount( ); i++ ) { columnArray[i] = new Column( ); String name = metaData.getColumnName( i ); columnArray[i].setName( name ); String label = metaData.getColumnLabel( i ); if ( label == null || label.length( ) <= 0 ) { label = name; } columnArray[i].setLabel( label ); columnArray[i].setVisibility( new Boolean( true ) ); } resultSetArray[k].setColumn( columnArray ); } } } catch ( BirtException e ) { AxisFault fault = new AxisFault( ); fault.setFaultCode( new QName( "ReportEngineService.getMetaData( )" ) ); //$NON-NLS-1$ fault.setFaultString( e.getLocalizedMessage( ) ); throw fault; } catch ( Exception e ) { AxisFault fault = new AxisFault( ); fault.setFaultCode( new QName( "ReportEngineService.getMetaData( )" ) ); //$NON-NLS-1$ fault.setFaultString( e.getLocalizedMessage( ) ); throw fault; } finally { dataTask.close( ); } return resultSetArray; } /** * Extract data. * * @param document * @param id * @param columns * @param filters * @param locale * @param outputStream * @throws RemoteException */ synchronized public void extractData( IReportDocument document, String resultSetName, Collection columns, Locale locale, ServletOutputStream outputStream ) throws RemoteException { assert document != null; assert resultSetName != null && resultSetName.length( ) > 0; assert columns != null && !columns.isEmpty( ); String[] columnNames = new String[columns.size( )]; Iterator iSelectedColumns = columns.iterator( ); for ( int i = 0; iSelectedColumns.hasNext( ); i++ ) { columnNames[i] = ( String ) iSelectedColumns.next( ); } IDataExtractionTask dataTask = null; IExtractionResults result = null; IDataIterator iData = null; try { dataTask = engine.createDataExtractionTask( document ); dataTask.selectResultSet( resultSetName ); dataTask.selectColumns( columnNames ); dataTask.setLocale( locale ); result = dataTask.extract( ); if ( result != null ) { IResultMetaData iMetaData = result.getResultMetaData( ); iData = result.nextResultIterator( ); if ( iData != null && iMetaData != null ) { StringBuffer buf = new StringBuffer( ); // Captions String caption = iMetaData.getColumnLabel( 0 ); if ( caption != null ) { buf.append( caption ); } else { buf.append( iMetaData.getColumnName( 0 ) ); } for ( int i = 1; i < columnNames.length; i++ ) { buf.append( ',' ); //$NON-NLS-1$ caption = iMetaData.getColumnLabel( i ); if ( caption != null ) { buf.append( caption ); } else { buf.append( iMetaData.getColumnName( i ) ); } } outputStream.println( buf.toString( ) ); buf.delete( 0, buf.length( ) ); // Data while ( iData.next( ) ) { String value = null; try { value = cvsConvertor( ( String ) DataTypeUtil .convert( iData.getValue( columnNames[0] ), DataType.STRING_TYPE ) ); } catch ( Exception e ) { value = null; } if ( value != null ) { buf.append( value ); } for ( int i = 1; i < columnNames.length; i++ ) { buf.append( ',' ); //$NON-NLS-1$ try { value = cvsConvertor( ( String ) DataTypeUtil .convert( iData.getValue( columnNames[i] ), DataType.STRING_TYPE ) ); } catch ( Exception e ) { value = null; } if ( value != null ) { buf.append( value ); } } outputStream.println( buf.toString( ) ); buf.delete( 0, buf.length( ) ); } } } } catch( Exception e ) { AxisFault fault = new AxisFault( ); fault.setFaultCode( new QName( "ReportEngineService.extractData( )" ) ); //$NON-NLS-1$ fault.setFaultString( e.getLocalizedMessage( ) ); throw fault; } finally { if ( iData != null ) { iData.close( ); } if ( result != null ) { result.close( ); } if ( dataTask != null ) { dataTask.close( ); } } } /** * CSV format convertor. Here is the rule. * * 1) Fields with embedded commas must be delimited with double-quote characters. * 2) Fields that contain double quote characters must be surounded by double-quotes, and * the embedded double-quotes must each be represented by a pair of consecutive double quotes. * 3) A field that contains embedded line-breaks must be surounded by double-quotes. * 4) Fields with leading or trailing spaces must be delimited with double-quote characters. * * @param value * @return * @throws RemoteException */ synchronized private String cvsConvertor( String value ) throws RemoteException { if ( value == null ) { return null; } value = value.replaceAll( "\"", "\"\"" ); //$NON-NLS-1$ //$NON-NLS-2$ boolean needQuote = false; needQuote = ( value.indexOf( ',' ) != -1 ) || ( value.indexOf( '"' ) != -1 ) //$NON-NLS-1$ //$NON-NLS-2$ || ( value.indexOf( 0x0A ) != -1 ) || value.startsWith( " " ) || value.endsWith( " " ); //$NON-NLS-1$ //$NON-NLS-2$ value = needQuote ? "\"" + value + "\"" : value; //$NON-NLS-1$ //$NON-NLS-2$ return value; } /** * Prepare the report parameters. * * @param request * @param task * @param configVars * @param locale * @return */ synchronized public HashMap parseParameters( HttpServletRequest request, IGetParameterDefinitionTask task, Map configVars, Locale locale ) { assert task != null; HashMap params = new HashMap( ); Collection parameterList = task.getParameterDefns( false ); for ( Iterator iter = parameterList.iterator( ); iter.hasNext( ); ) { ScalarParameterDefn parameterObj = ( ScalarParameterDefn ) iter.next( ); String paramValue = null; Object paramValueObj = null; ScalarParameterHandle paramHandle = (ScalarParameterHandle) parameterObj.getHandle( ); String paramName = paramHandle.getName( ); String format = paramHandle.getFormat( ); // Get default value from task ReportParameterConverter converter = new ReportParameterConverter( format, locale ); if ( ParameterAccessor.isReportParameterExist( request, paramName ) ) { // Get value from http request paramValue = ParameterAccessor.getReportParameter( request, paramName, paramValue ); paramValueObj = converter.parse( paramValue, getEngineDataType( paramHandle.getDataType( ) ) ); } else if ( ParameterAccessor.isDesigner( request ) && configVars.containsKey( paramName ) ) { // Get value from test config String configValue = (String) configVars.get( paramName ); ReportParameterConverter cfgConverter = new ReportParameterConverter( format, Locale.US ); paramValueObj = cfgConverter.parse( configValue, getEngineDataType( paramHandle.getDataType( ) ) ); } else { paramValueObj = task.getDefaultValue( paramHandle.getName( ) ); } params.put( paramName, paramValueObj ); } return params; } /** * Check whether missing parameter or not. * * @param task * @param parameters * @return */ synchronized public boolean validateParameters( IGetParameterDefinitionTask task, Map parameters ) { assert task != null; assert parameters != null; boolean missingParameter = false; Collection parameterList = task.getParameterDefns( false ); for ( Iterator iter = parameterList.iterator( ); iter.hasNext( ); ) { ScalarParameterDefn parameterObj = ( ScalarParameterDefn ) iter.next( ); ScalarParameterHandle paramHandle = (ScalarParameterHandle) parameterObj.getHandle( ); String parameterName = paramHandle.getName( ); Object parameterValue = parameters.get( parameterName ); if ( paramHandle.isHidden( ) ) { continue; } if ( parameterValue == null && !paramHandle.allowNull( ) ) { missingParameter = true; break; } if ( DesignChoiceConstants.PARAM_TYPE_STRING.equals( paramHandle.getDataType( ) ) ) { String parameterStringValue = ( String ) parameterValue; if ( parameterStringValue != null && parameterStringValue.length( ) <= 0 && !paramHandle.allowBlank( ) ) { missingParameter = true; break; } } } return missingParameter; } /** * Parameter typer convertion. * * @param type * @return */ synchronized public int getEngineDataType( String type ) { if ( DesignChoiceConstants.PARAM_TYPE_BOOLEAN.equals( type ) ) { return IScalarParameterDefn.TYPE_BOOLEAN; } else if ( DesignChoiceConstants.PARAM_TYPE_DATETIME.equals( type ) ) { return IScalarParameterDefn.TYPE_DATE_TIME; } else if ( DesignChoiceConstants.PARAM_TYPE_DECIMAL.equals( type ) ) { return IScalarParameterDefn.TYPE_DECIMAL; } else if ( DesignChoiceConstants.PARAM_TYPE_FLOAT.equals( type ) ) { return IScalarParameterDefn.TYPE_FLOAT; } else if ( DesignChoiceConstants.PARAM_TYPE_STRING.equals( type ) ) { return IScalarParameterDefn.TYPE_STRING; } return IScalarParameterDefn.TYPE_ANY; } }