Discussions
Categories
Groups
Community Home
Categories
INTERNAL ENABLEMENT
POPULAR
PUBLIC CLOUD
PRIVATE CLOUD
Quick Links
MY LINKS
HELPFUL TIPS
Back to website
Home
Intelligence (Analytics)
Error Running Drill-Through Report
bmac
I am attempting to run and render a drill-through, master-detail report from a java application.
In the report designer everything works fine. The hyperlink options are set to produce PDF output.
When the report is run the master displays properly in Adobe Reader, but when I click the link to run the detail report the following error appears:
Firefox can't find the file at /c:/ddt/reports/ingres/run?__report=c:/DDT/reports/BIRT/TriggerDef.rptdesign&TriggerName=[ddt_symbol_rename]&__overwrite=true.
The directory "c:/ddt/reports/ingres" is the output directory for my reports, not the location for the rptdesign files. Everything else on the line is correct. Hovering over the link in the master report display shows "file:///c|/ddt/reports/ingres/run?..." I don't understand what BIRT is trying to do.
Please explain what is happening.
Thanks,
Bmac
Find more posts tagged with
Comments
JasonW
Do you have the viewer deployed or are you only using the RE API?
Jason
bmac
Just the RE API, I think. I am experimenting and learning so things may not be set up properly.<br />
<br />
Bmac<br />
<br />
<blockquote class='ipsBlockquote' data-author="'JasonW'" data-cid="73966" data-time="1298653014" data-date="25 February 2011 - 09:56 AM"><p>
Do you have the viewer deployed or are you only using the RE API?<br />
<br />
Jason<br /></p></blockquote>
JasonW
If you are just using the API you have to handle the drill throughs yourself. By default it is trying to run the report with the viewer, hence the /run. The links are built by the default impelmentation of the IHTMLActionHandler interface. You can build your own and then set it in the render options like:<br />
<br />
HTMLRenderOption options = new HTMLRenderOption(); <br />
options.setOutputFileName("output/resample/master.html");<br />
options.setOutputFormat("html");<br />
options.setHtmlRtLFlag(false);<br />
options.setEnableAgentStyleEngine(true);<br />
options.setEmbeddable(true);<br />
options.setBaseURL("<a class='bbc_url' href='
http://localhost:8080/birt2.6.1/frameset'>http://localhost:8080/birt2.6.1/frameset"</a>);<br
/>
//options.setActionHandler(new HTMLActionHandler());<br />
options.setActionHandler(new MyActionHandler());<br />
<br />
In this example it is calling the viewer deployed on Tomcat to run the detail report. MyActionHandler code builds the drill hyperlink:<br />
<br />
package REAPI;<br />
import java.io.File;<br />
import java.io.UnsupportedEncodingException;<br />
import java.net.MalformedURLException;<br />
import java.net.URL;<br />
import java.net.URLEncoder;<br />
import java.util.Iterator;<br />
import java.util.List;<br />
import java.util.Map;<br />
import java.util.logging.Logger;<br />
<br />
import org.eclipse.birt.report.engine.api.EngineConstants;<br />
import org.eclipse.birt.report.engine.api.HTMLActionHandler;<br />
import org.eclipse.birt.report.engine.api.HTMLRenderContext;<br />
import org.eclipse.birt.report.engine.api.IAction;<br />
import org.eclipse.birt.report.engine.api.IHTMLActionHandler;<br />
import org.eclipse.birt.report.engine.api.PDFRenderContext;<br />
import org.eclipse.birt.report.engine.api.script.IReportContext;<br />
import org.eclipse.birt.report.model.api.util.ParameterValidationUtil;<br />
<br />
import com.ibm.icu.math.BigDecimal;<br />
<br />
/**<br />
* Defines a default action handler for HTML output format<br />
*/<br />
public class MyActionHandler implements IHTMLActionHandler<br />
{<br />
<br />
/** logger */<br />
protected Logger log = Logger<br />
.getLogger( HTMLActionHandler.class.getName( ) );<br />
<br />
/**<br />
* Get URL of the action.<br />
* <br />
*
@param
actionDefn<br />
*
@param
context<br />
*
@return
URL<br />
*/<br />
public String getURL( IAction actionDefn, IReportContext context )<br />
{<br />
Object renderContext = getRenderContext( context );<br />
return getURL( actionDefn, renderContext );<br />
}<br />
<br />
/*<br />
* (non-Javadoc)<br />
* <br />
*
@see
org.eclipse.birt.report.engine.api2.IHTMLActionHandler#getURL(org.eclipse.birt.report.engine.api2.IAction,<br />
* java.lang.Object)<br />
*/<br />
public String getURL( IAction actionDefn, Object context )<br />
{<br />
if ( actionDefn == null )<br />
{<br />
return null;<br />
}<br />
String url = null;<br />
switch ( actionDefn.getType( ) )<br />
{<br />
case IAction.ACTION_BOOKMARK :<br />
if ( actionDefn.getActionString( ) != null )<br />
{<br />
url = "#" + actionDefn.getActionString( );<br />
}<br />
break;<br />
case IAction.ACTION_HYPERLINK :<br />
url = actionDefn.getActionString( );<br />
break;<br />
case IAction.ACTION_DRILLTHROUGH :<br />
url = buildDrillAction( actionDefn, context );<br />
break;<br />
default :<br />
return null;<br />
}<br />
return url;<br />
}<br />
<br />
/**<br />
* builds URL for drillthrough action<br />
* <br />
*
@param
action<br />
* instance of the IAction instance<br />
*
@param
context<br />
* the context for building the action string<br />
*
@return
a URL<br />
*/<br />
protected String buildDrillAction( IAction action, Object context )<br />
{<br />
String baseURL = null;<br />
if ( context != null )<br />
{<br />
if ( context instanceof HTMLRenderContext )<br />
{<br />
baseURL = ( (HTMLRenderContext) context ).getBaseURL( );<br />
}<br />
if ( context instanceof PDFRenderContext )<br />
{<br />
baseURL = ( (PDFRenderContext) context ).getBaseURL( );<br />
}<br />
}<br />
<br />
if ( baseURL == null )<br />
{<br />
baseURL = "run";<br />
}<br />
StringBuffer link = new StringBuffer( );<br />
String reportName = getReportName( action );<br />
<br />
if ( reportName != null && !reportName.equals( "" ) ) //$NON-NLS-1$<br />
{<br />
String format = action.getFormat( );<br />
if ( !"html".equalsIgnoreCase( format ) )<br />
{<br />
link.append( baseURL.replaceFirst( "frameset", "run" ) ); //$NON-NLS-1$ //$NON-NLS-2$<br />
}<br />
else<br />
{<br />
link.append( baseURL );<br />
}<br />
<br />
link<br />
.append( reportName.toLowerCase( )<br />
.endsWith( ".rptdocument" ) ? "?__document=" : "?__report=" ); //$NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-1$<br />
<br />
try<br />
{<br />
link.append( URLEncoder.encode( reportName, "UTF-8" ) ); //$NON-NLS-1$<br />
}<br />
catch ( UnsupportedEncodingException e1 )<br />
{<br />
// It should not happen. Does nothing<br />
}<br />
<br />
// add format support<br />
if ( format != null && format.length( ) > 0 )<br />
{<br />
link.append( "&__format=" + format ); //$NON-NLS-1$<br />
}<br />
<br />
// Adds the parameters<br />
if ( action.getParameterBindings( ) != null )<br />
{<br />
Iterator paramsIte = action.getParameterBindings( ).entrySet( )<br />
.iterator( );<br />
while ( paramsIte.hasNext( ) )<br />
{<br />
Map.Entry entry = (Map.Entry) paramsIte.next( );<br />
try<br />
{<br />
String key = (String) entry.getKey( );<br />
Object valueObj = entry.getValue( );<br />
<br />
<br />
if ( valueObj != null )<br />
{<br />
if ( valueObj instanceof List )<br />
{<br />
if ( ( (List) valueObj ).size( ) == 1 )<br />
{<br />
valueObj = ( (List) valueObj ).get( 0 );<br />
}<br />
else<br />
{<br />
valueObj = ( (List) valueObj ).toArray( );<br />
}<br />
}<br />
<br />
Object[] values;<br />
if ( valueObj instanceof Object[] )<br />
{<br />
values = (Object[]) valueObj;<br />
}<br />
else<br />
{<br />
values = new Object[1];<br />
values[0] = valueObj;<br />
}<br />
<br />
for ( int i = 0; i < values.length; i++ )<br />
{<br />
// TODO: here need the get the format from the<br />
// parameter.<br />
String value = getDisplayValue( values
);<br />
<br />
if ( value != null )<br />
{<br />
link<br />
.append( "&" + URLEncoder.encode( key, "UTF-8" ) <br />
+ "=" + URLEncoder.encode( value, "UTF-8" ) ); <br />
}<br />
<br />
}<br />
} <br />
<br />
}<br />
catch ( UnsupportedEncodingException e )<br />
{<br />
// Does nothing<br />
}<br />
}<br />
}<br />
<br />
// Adding overwrite.<br />
link.append( "&__overwrite=true" ); //$NON-NLS-1$<br />
<br />
// The search rules are not supported yet.<br />
if ( /*<br />
* !"pdf".equalsIgnoreCase( format ) &&<br />
*/action.getBookmark( ) != null )<br />
{<br />
<br />
try<br />
{<br />
// In RUN mode, don't support bookmark as parameter<br />
if ( baseURL.lastIndexOf( "run" ) > 0 )<br />
{<br />
link.append( "#" ); //$NON-NLS-1$<br />
}<br />
else<br />
{<br />
link.append( "&__bookmark=" ); //$NON-NLS-1$<br />
}<br />
<br />
link.append( URLEncoder.encode( action.getBookmark( ),<br />
"UTF-8" ) ); //$NON-NLS-1$<br />
}<br />
catch ( UnsupportedEncodingException e )<br />
{<br />
// Does nothing<br />
}<br />
}<br />
}<br />
<br />
return link.toString( );<br />
}<br />
<br />
/**<br />
* Append report design name into a StringBuffer.<br />
* <br />
*
@param
buffer <br />
*
@param
reportName<br />
*/<br />
protected void appendReportDesignName( StringBuffer buffer,<br />
String reportName )<br />
{<br />
buffer.append( "?__report=" ); //$NON-NLS-1$<br />
try<br />
{<br />
buffer.append( URLEncoder.encode( reportName, "UTF-8" ) ); //$NON-NLS-1$<br />
}<br />
catch ( UnsupportedEncodingException e1 )<br />
{<br />
// It should not happen. Does nothing<br />
}<br />
}<br />
<br />
/**<br />
* Append format.<br />
* <br />
*
@param
buffer<br />
*
@param
format<br />
*/<br />
protected void appendFormat( StringBuffer buffer, String format )<br />
{<br />
if ( format != null && format.length( ) > 0 )<br />
{<br />
buffer.append( "&__format=" + format );//$NON-NLS-1$<br />
}<br />
}<br />
<br />
/**<br />
* Append parameter.<br />
* <br />
*
@param
buffer<br />
*
@param
key<br />
*
@param
valueObj<br />
*/<br />
protected void appendParamter( StringBuffer buffer, String key,<br />
Object valueObj )<br />
{<br />
if ( valueObj != null )<br />
{<br />
try<br />
{<br />
key = URLEncoder.encode( key, "UTF-8" );<br />
String value = valueObj.toString( );<br />
value = URLEncoder.encode( value, "UTF-8" );<br />
buffer.append( "&" );<br />
buffer.append( key );<br />
buffer.append( "=" );<br />
buffer.append( value );<br />
}<br />
catch ( UnsupportedEncodingException e )<br />
{<br />
// Does nothing<br />
}<br />
}<br />
}<br />
<br />
/**<br />
* Append bookmark as parameter .<br />
* <br />
*
@param
buffer<br />
*
@param
bookmark<br />
*/<br />
protected void appendBookmarkAsParamter( StringBuffer buffer,<br />
String bookmark )<br />
{<br />
try<br />
{<br />
if ( bookmark != null && bookmark.length( ) != 0 )<br />
{<br />
bookmark = URLEncoder.encode( bookmark, "UTF-8" );<br />
buffer.append( "&__bookmark=" );//$NON-NLS-1$<br />
buffer.append( bookmark );<br />
}<br />
}<br />
catch ( UnsupportedEncodingException e )<br />
{<br />
<br />
}<br />
}<br />
<br />
/**<br />
* Append bookmark.<br />
* <br />
*
@param
buffer<br />
*
@param
bookmark<br />
*/<br />
protected void appendBookmark( StringBuffer buffer, String bookmark )<br />
{<br />
try<br />
{<br />
if ( bookmark != null && bookmark.length( ) != 0 )<br />
{<br />
bookmark = URLEncoder.encode( bookmark, "UTF-8" );<br />
buffer.append( "#" );//$NON-NLS-1$<br />
buffer.append( bookmark );<br />
}<br />
}<br />
catch ( UnsupportedEncodingException e )<br />
{<br />
}<br />
}<br />
<br />
/**<br />
* Get report name.<br />
* <br />
*
@param
action<br />
*
@return<
;br />
*/<br />
String getReportName( IAction action )<br />
{<br />
String systemId = action.getSystemId( );<br />
String reportName = action.getReportName( );<br />
if ( systemId == null )<br />
{<br />
return reportName;<br />
}<br />
// if the reportName is an URL, use it directly<br />
try<br />
{<br />
URL url = new URL( reportName );<br />
if ( "file".equals( url.getProtocol( ) ) )<br />
{<br />
return url.getFile( );<br />
}<br />
return url.toExternalForm( );<br />
}<br />
catch ( MalformedURLException ex )<br />
{<br />
}<br />
// if the system id is the URL, merget the report name with it<br />
try<br />
{<br />
URL root = new URL( systemId );<br />
URL url = new URL( root, reportName );<br />
if ( "file".equals( url.getProtocol( ) ) )<br />
{<br />
return url.getFile( );<br />
}<br />
return url.toExternalForm( );<br />
}<br />
catch ( MalformedURLException ex )<br />
{<br />
<br />
}<br />
// now the root should be a file and the report name is a file also<br />
File file = new File( reportName );<br />
if ( file.isAbsolute( ) )<br />
{<br />
return reportName;<br />
}<br />
<br />
try<br />
{<br />
URL root = new File( systemId ).toURL( );<br />
URL url = new URL( root, reportName );<br />
assert "file".equals( url.getProtocol( ) );<br />
return url.getFile( );<br />
}<br />
catch ( MalformedURLException ex )<br />
{<br />
}<br />
return reportName;<br />
}<br />
<br />
/**<br />
* Get render context.<br />
* <br />
*
@param
context<br />
*
@return<
;br />
*/<br />
protected Object getRenderContext( IReportContext context )<br />
{<br />
if ( context == null )<br />
{<br />
return null;<br />
}<br />
Map appContext = context.getAppContext( );<br />
if ( appContext != null )<br />
{<br />
String renderContextKey = EngineConstants.APPCONTEXT_HTML_RENDER_CONTEXT;<br />
String format = context.getOutputFormat( );<br />
if ( "pdf".equalsIgnoreCase( format ) )<br />
{<br />
renderContextKey = EngineConstants.APPCONTEXT_PDF_RENDER_CONTEXT;<br />
}<br />
return appContext.get( renderContextKey );<br />
}<br />
return null;<br />
}<br />
<br />
/**<br />
* Get display value.<br />
* <br />
*
@param
value<br />
*
@return<
;br />
*/<br />
String getDisplayValue( Object value )<br />
{<br />
if ( value == null )<br />
return null;<br />
<br />
if ( value instanceof Float || value instanceof Double<br />
|| value instanceof BigDecimal )<br />
{<br />
return value.toString( );<br />
}<br />
return ParameterValidationUtil.getDisplayValue( value );<br />
}<br />
<br />
}<br />
<br />
Jason
bmac
Jason,<br />
<br />
This is helping but has also raised several new questions.<br />
<ul class='bbc'><li>Does this mean that the detail report must be rendered in HTML or was this only an example?</li><li>Is Tomcat required?</li><li>When setting BaseURL, where is "frameset"? I cannot locate it in my Tomcat directory tree. However, I have only tried a simple demo report in the viewer and may not have it configured properly.</li></ul>
<br />
That is probably enough for now.<br />
Thanks for helping,<br />
Bmac
JasonW
A Java EE server like Tomcat is required if you want to use the BIRT Viewer. The /frameset servlet mapping is used to run and render a report. If you use the viewer the API is not required. See
http://www.eclipse.org/birt/phoenix/deploy/viewerSetup.php
and
http://www.eclipse.org/birt/phoenix/deploy/viewerUsageMain.php
For more details.
Jason
bmac
HI Jason,
The drill-through is working now. The following is a summary of what happened and my current understanding. If I say something wrong, please correct me.
I was trying to run a drill-through master-detail report from a Java application without using a Java EE server (Tomcat) or the birt-viewer. That is not possible. Plain reports, without drill-through, worked fine.
Drill-through will work in the report designer because the designer seems to contain its own viewer and does not need Tomcat.
The application must set the render options baseURL to the birt-viewer/frameset and also provide its own ActionHandler to build the correct hyperlinks into the master report. The code you provided shows how to do this.
To be able to reference rptdesign files with an absolute path, I edited the birt-viewer web.xml file and set WORKING_FOLDER_ACCESS_ONLY parameter to false. There is probably a way to set this parameter dynamically in the application, but I have not looked for that yet.
So, it is running and I am off to the next problem.
Thanks for your help,
Bmac
JasonW
This is essentially correct. You could get drill through to work in a Java app (standalone) if you implemented the action handler to call the java command line though.
Jason