Home
Analytics
Having Problems - Property Binding with Custom Data Source and RE API
qos
Hello,
I could really use some help because I don't have any clue of what is happening.
Info
- I am using BIRT 2.3.2.
- I have a custom data source with 2 properties.
- I have a rptlibrary with 2 parameters and data source property binding to those parameters.
- I have a design that uses the library datasource, data set and parameters.
Report Designer - Works
- Added Custom Data Source to plugins
- Running the design as report, the parameters are asked and the binding is correctly done (connection to data source succeeds).
Report Engine API - Does Not Work
- Added Custom Data Source to birt_home/plugins
- Run the report using RE API and setting parameters with task.setParameterValue("parm", parm_value);
- The report has no data.
- (debug) The method open(Properties prop) does not have datasource properties value updated according to parameter value;
To know : I have created the same scenario using classic models sample database and eveything works fine so my thought is that the problem is with Custom Data Source but I can't figure out what because everything works fine in designer.
Any hint of what may be happening?
Find more posts tagged with
Comments
JasonW
Are you setting the resource folder to locate the rptlibrary? Is your custom data source in a jar?
Use config.setResourceFolder to set the rptlibrary path.
The viewer uses a couple of settings to configure classpaths:
//Parent classloader
config.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY, this.getClass().getClassLoader());
//scriptlib directory for event handler jars
config.getAppContext().put(EngineConstants.WEBAPP_CLASSPATH_KEY, "C:\\work\\workspaces\\2.5.2workspaces\\EclipseCon2010\\APIs\\Reports\\eventjar.jar");
Jason
qos
Jason,
Thank you for your answer, I have tried to do what you've said but it didn't work. I must be doing something else wrong. I forgot to say that my code will run in an eclipse application and produce rptdocuments.
I've managed to build a tester with sampledb that is exactly the same and doesn't work also. I've attached design and below is my code. (I've tried to attach library but it says that is not permitted?... xml source is after the code)
EngineConfig dConfig = new EngineConfig();
dConfig.setBIRTHome("C:/birt-runtime-2_3_2/ReportEngine" );
//where the design and library are
dConfig.setResourcePath("C:\\birt2.3.2\\Printing\\PrintingTemplates");
dConfig.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY, this.getClass().getClassLoader());
ReportEngine engine = new ReportEngine( dConfig );
IReportRunnable runnable = null;
//Open the report design
IReportRunnable design = engine.openReportDesign("C:\\birt2.3.2\\Printing\\PrintingTemplates\\report_params.rptdesign");
//Create task to run and render the report,
IRunAndRenderTask task = engine.createRunAndRenderTask(design);
//parameter with wrong value to validate if is working
task.setParameterValue("parm1", "jdbc:classicmodels:sampledbx");
task.validateParameters();
//Setup rendering to HTML
HTMLRenderOption options = new HTMLRenderOption();
options.setOutputFileName("C:\\Users\\tfrias\\Desktop\\teste.html");
options.setOutputFormat("html");
options.setEmbeddable(false);
task.setRenderOption(options);
//run and render report
task.run();
task.close();
report_params.rptlibrary
<?xml version="1.0" encoding="UTF-8"?>
<library xmlns="
http://www.eclipse.org/birt/2005/design"
; version="3.2.17" id="1">
<property name="createdBy">Eclipse BIRT Designer Version 2.3.2.r232_20090202 Build <2.3.2.v20090218-0730></property>
<property name="units">in</property>
<list-property name="propertyBindings">
<structure>
<property name="name">odaURL</property>
<property name="id">5</property>
<expression name="value">params["parm1"]</expression>
</structure>
</list-property>
<property name="theme">defaultTheme</property>
<parameters>
<scalar-parameter name="parm1" id="8">
<property name="valueType">static</property>
<property name="dataType">string</property>
<property name="paramType">simple</property>
<text-property name="promptText">Par?metro</text-property>
<property name="controlType">text-box</property>
<property name="defaultValue">jdbc:classicmodels:sampledb</property>
<property name="distinct">true</property>
<structure name="format">
<property name="category">Unformatted</property>
</structure>
</scalar-parameter>
</parameters>
<data-sources>
<oda-data-source extensionID="org.eclipse.birt.report.data.oda.jdbc" name="Data Source" id="5">
<property name="odaDriverClass">org.eclipse.birt.report.data.oda.sampledb.Driver</property>
<property name="odaURL">jdbc:classicmodels:sampledb</property>
<property name="odaUser">ClassicModels</property>
</oda-data-source>
</data-sources>
<data-sets>
<oda-data-set extensionID="org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet" name="Data Set" id="6">
<list-property name="columnHints">
<structure>
<property name="columnName">CUSTOMERNUMBER</property>
<property name="displayName">CUSTOMERNUMBER</property>
</structure>
<structure>
<property name="columnName">CUSTOMERNAME</property>
<property name="displayName">CUSTOMERNAME</property>
</structure>
</list-property>
<structure name="cachedMetaData">
<list-property name="resultSet">
<structure>
<property name="position">1</property>
<property name="name">CUSTOMERNUMBER</property>
<property name="dataType">integer</property>
</structure>
<structure>
<property name="position">2</property>
<property name="name">CUSTOMERNAME</property>
<property name="dataType">string</property>
</structure>
</list-property>
</structure>
<property name="dataSource">Data Source</property>
<list-property name="resultSet">
<structure>
<property name="position">1</property>
<property name="name">CUSTOMERNUMBER</property>
<property name="nativeName">CUSTOMERNUMBER</property>
<property name="dataType">integer</property>
<property name="nativeDataType">4</property>
</structure>
<structure>
<property name="position">2</property>
<property name="name">CUSTOMERNAME</property>
<property name="nativeName">CUSTOMERNAME</property>
<property name="dataType">string</property>
<property name="nativeDataType">12</property>
</structure>
</list-property>
<property name="queryText">select customernumber, customername
from customers</property>
<xml-property name="designerValues"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<model:DesignValues xmlns:design="
http://www.eclipse.org/datatools/connectivity/oda/design"
; xmlns:model="
http://www.eclipse.org/birt/report/model/adapter/odaModel">
;
<Version>1.0</Version>
<design:ResultSets derivedMetaData="true">
<design:resultSetDefinitions>
<design:resultSetColumns>
<design:resultColumnDefinitions>
<design:attributes>
<design:name>CUSTOMERNUMBER</design:name>
<design:position>1</design:position>
<design:nativeDataTypeCode>4</design:nativeDataTypeCode>
<design:precision>10</design:precision>
<design:scale>0</design:scale>
<design:nullability>Nullable</design:nullability>
<design:uiHints>
<design:displayName>CUSTOMERNUMBER</design:displayName>
</design:uiHints>
</design:attributes>
<design:usageHints>
<design:label>CUSTOMERNUMBER</design:label>
<design:formattingHints>
<design:displaySize>11</design:displaySize>
</design:formattingHints>
</design:usageHints>
</design:resultColumnDefinitions>
<design:resultColumnDefinitions>
<design:attributes>
<design:name>CUSTOMERNAME</design:name>
<design:position>2</design:position>
<design:nativeDataTypeCode>12</design:nativeDataTypeCode>
<design:precision>50</design:precision>
<design:scale>0</design:scale>
<design:nullability>Nullable</design:nullability>
<design:uiHints>
<design:displayName>CUSTOMERNAME</design:displayName>
</design:uiHints>
</design:attributes>
<design:usageHints>
<design:label>CUSTOMERNAME</design:label>
<design:formattingHints>
<design:displaySize>50</design:displaySize>
</design:formattingHints>
</design:usageHints>
</design:resultColumnDefinitions>
</design:resultSetColumns>
</design:resultSetDefinitions>
</design:ResultSets>
</model:DesignValues>]]></xml-property>
</oda-data-set>
</data-sets>
<themes>
<theme name="defaultTheme" id="4"/>
</themes>
<page-setup>
<simple-master-page name="NewSimpleMasterPage" id="3"/>
</page-setup>
</library>
qos
Jason,
Googling my problem I came across a newsgroup thread in 2007 that looks exactly the problem i am having.
http://dev.eclipse.org/newslists/news.eclipse.birt/msg23035.html
(you probably are same Jason or is just a coincidence...)
I've looked at mentioned bugzilla reports and in what it seems to be the final conclusion is
"We have reviewed this and concluded that this is an intended behavior of the
Property Binding feature. Property binding is designed to "bind" or associate a
data element with properties local to a report design (such as its report
parameters). It is therefore always local to a report. It will not be copied
together with the data set or data source when the data element is copied from
one library/report to another"
https://bugs.eclipse.org/bugs/show_bug.cgi?id=131304
Is this true? It doesn't make much sense since it works in designer environment...
If this is true what should be my approach to the problem?
JasonW
In the lib you posted remove the property binding expression and put the following beforeOpen script on the datasource:
this.setExtensionProperty("odaURL", params["parm1"].value);
Jason
qos
It works! With my custom data source as well!
Thank you Jason for the patience and support!
(it works as well without setting resource path, i thought it would since i have library and template in same folder and had the idea that in that way library is correctly loaded)
JasonW
Glad to hear it is working.
Jason
qos
Hello Jason,
I am sorry to bother you again but solving my first problem, brought me another one.
I need to have the connection working at design time, that means that my property value can not depend only on runtime values. I have tried 2 ideas but don't seem to work:
- using a condition to only execute script at runtime (found it somewhere here in the forum)and having property value filled in report
if(reportContext.getHttpServletRequest()!=null) { .... }
<oda-data-source ...>
<property name="prop">somepath</property>
</oda-datasource>
- having a default value in parameter
Can you give some help?
Thanks in advance
qos
I can also tell you that managing to resolve library context physical path would solve my problem. Meaning that I have two connection properties, one is datasource metadata location , the other is datasource runtime data.
The second one was my first issue and thanks to you, solved because I only need to set its value at runtime.
The first one, the metadata, I need at design time and I don't want to use absolute path because I never know where my users will have their designer. But one thing I know is data datasource metadata xml file is always in same folder that the library and template so one (probably stupid) question I have is if there isn't a native variable that represents library Properties/General/path like
<oda-data-source ...>
<property name="metadata_path"> {context_path}/metadata.xml </property>
</oda-data-source...>
I have tried this beforeopen script but it only works at runtime ....
var name = reportContext.getDesignHandle().fileName;
var xmlname = name.replace("rpttemplate", "xml");
xmlname=xmlname.replace("file:/", "");
this.setExtensionProperty("metadata_path", xmlname)
Thanks again ....
JasonW
If the xml file is in the resource folder of the designer you could use a script like:
var httpr = reportContext.getHttpServletRequest();
if( httpr != null && httpr.getAttribute("attributeBean").isDesigner()){
var str = reportContext.getResource("testdata.xml").toString();
this.setExtensionProperty("FILELIST",str );
}
Jason
JasonW
btw the above was an example of swapping the xml file for the xml datasource on the fly. Same approach may work.
Jason
qos
Thanks you Jason for your response but i didn't make myself clear. When i refer to designer i am talking about Data Explorer and not about running report viewer (i think the script you gave me is for running report viewer). <br />
<br />
What I deliver to my users is a library/template with data source and data sets created, my goal is that when they open the template in designer, the fields for each data set are listed according do my custom data source, and for that, xml metadata path is needed. so I would need something in beforeOpen Event like the script I've posted before.<br />
<br />
var name = <strong class='bbc'>reportContext.getDesignHandle().fileName; --> I think the problem is i don't have report context ?...</strong> <br />
var xmlname = name.replace("rpttemplate", "xml");<br />
xmlname=xmlname.replace("file:/", "");<br />
this.setExtensionProperty("metadata_path", xmlname)<br />
<br />
Thank you
qos
I can add that having reportContext.someMethod in my beforeOpen script causes some error because the my IConnecion open method is not even invoked.
this.setExtensionProperty("metadata_path" , some_absolute_path) works perfectly and populates the data sets in the data explorer, I just need a way to compute <some_absolute_path> ....
JasonW
Ok, I see now. I think one of the problems is in the preview the design location comes back different than in a preview of the report. Put a log in like this<br />
<br />
yz = reportContext.getDesignHandle().fileName;<br />
importPackage( Packages.java.io );<br />
out = new PrintWriter( new FileWriter( "c:/test/fileevents.txt", true ) );<br />
out.println( yz);<br />
out.close();<br />
<br />
And then preview the data set and then preview the report and you will see what I mean. Another option is to do something like:<br />
<br />
importPackage(Packages.org.eclipse.core.resources);<br />
//projects = ResourcesPlugin.getWorkspace( ).getRoot( ).getProjects( );<br />
//projectString = ""; <br />
//for ( i = 0; i < projects.length; i++ )<br />
//{<br />
// proj = projects
;<br />
// projectString += proj.getName( ) + File.pathSeparator;<br />
//}<br />
<br />
wkspcroot = ResourcesPlugin.getWorkspace().getRoot();<br />
myProject = wkspcroot.getProject("BIRT Reports");<br />
specFolder = myProject.getFolder("demo").getLocation();<br />
<br />
BTW this was done in the beforeOpen of the dataset in JavaScript.<br />
<br />
Jason
qos
Hello Jason,
Thank you so much for your time. I have everything working now
both in designer and report generation.
I used your first script, very similar to the one i've posted, which i thought it didn't work because i am working with a library, and in the library the fields are never populated whith yours or my script (?...) . By chance, and to check what you were saying about path, i've opened the template and the fields were populated. So my conclusion is that i would never, and won't, see the fields in library. No problem because the users, as expected, will have only access to the template.
After, I had to deal with everything working in runtime and designer. So i decided that only the runtimedata will be a parameter and the metadata will always be computed. And it is working perfectly. I leave my (ours) solution below, it can help someone.
Can thank enough...
Teresa
So my script for beforeopen data source event is now
var runtimedata =reportContext.getParameterValue("runtimedata_parm");
if(runtimedata!=null)
{
this.setExtensionProperty("runtimedata", runtimedata);
}
var name = reportContext.getDesignHandle().fileName;
var xmlname = name.replace("rpttemplate", "xml");
xmlname=xmlname.replace("file:/", "");
this.setExtensionProperty("metadata", xmlname)
And generating report I use
task.setParameterValue("runtimedata_parm", parm);
JasonW
Thanks for posting the final solution.
Jason