|
Re: Refresh Dataset using BIRT API [message #657405 is a reply to message #657267] |
Wed, 02 March 2011 16:56 |
|
Jan,
Can you give some details on what you are trying to do. Usually you
refresh a dataset when a query is changed in the designer. If the
dataset columns change at runtime all the bindings in report items will
need to be updated as well. The logic to know which dataset column
would go to what table column could get quite complex.
Jason
On 3/2/2011 4:43 AM, Jan Kohnert wrote:
> Hello.
>
> When running the BIRT Designer a data set can be refreshed using the
> data sets popup menus refresh command.
> I want to refresh a reports dataset using API at runtime. Is this
> possible? And when, how?
>
> Thank you,
> Jan
|
|
|
|
Re: Refresh Dataset using BIRT API [message #657670 is a reply to message #657525] |
Thu, 03 March 2011 15:43 |
|
Jan,
The bindings on a table will map the dataset to the table columns. You
can look at them in the properties view, binding tab. They are
referencing them by name. If the column names change the bindings will
have to be updated either through code or manual intervention. One way
around this is to change the bindings to not use the column name but to
use alias or the column number. For example my column binding for one
column is mapped to
PRODUCTCODE dataSetRow["PRODUCTCODE"]
I could change this to
PRODUCTCODE dataSetRow[1]
Keep in mind dataSetRow[0] always contains the row count.
Jason
On 3/3/2011 2:51 AM, Jan Kohnert wrote:
> Jason,
>
> The reports data sets queries are stored procedures (defined with the
> SQL Query page, not the stored procedure page). These procedures return
> a result set with named columns. From release to release the returned
> result set may change. We always are taking care that no column will
> ever disappear from the result set. But we can not guarantee that for a
> columns position. This results in BIRT not finding the columns anymore,
> because it is locking for the columns by index, not name (I'm guessing
> here). Since the reports being in use are customizable we do not want
> them to be in need of an update once a system update happens. Updating a
> dataset automatically at runtime has the goal to avoid exceptions being
> thrown once the columns positions have changed. (Or, with other words,
> to keep the reports being runnable.).
>
> Jan
>
|
|
|
|
Re: Refresh Dataset using BIRT API [message #658463 is a reply to message #658364] |
Tue, 08 March 2011 14:20 |
|
Verify that the columns that are lost are not in any binding in the
report. If they are not the report should continue to run.
Jason
On 3/8/2011 3:26 AM, Jan Kohnert wrote:
> Jason,
>
> the bindings used as output columns on a report will never change there
> names. But the data references by the data set might have additional
> columns. And some times it will also loose columns. But this are never
> columns used anywhere in the layout. I'll see to catch a excpetion
> message so I can illustrate my problem in a better way.
> Jan
|
|
|
Re: Refresh Dataset using BIRT API [message #661548 is a reply to message #657267] |
Fri, 25 March 2011 09:19 |
Jan Kohnert Messages: 196 Registered: July 2009 |
Senior Member |
|
|
Jason.
Unfortunately the work around is too complicated to offer BIRT reports for a professional health care product. To get reports run on a wide range of installed platforms using different product versions, it is not acceptable to manually check all reports after an update each time. The goal should be to have BIRT reports run as stable as possible. For us this is not guaranteed using BIRT 2.6.1. The bindings throwing exceptions under certain circumstances which make reports not being generated are THE major part speaking against BIRT.
This could be solved if it would be possible to not include any items into the bindings that are not being used as output or part of the output somewhere. To do that manually is to difficult and will result in people doing it wrong (For instance by pressing the 'Refresh' button of the 'Binding' tab in the 'Property Editor View, which result in all possible columns of a data set are included into a controls binding....). I belief, that the BIRT Designer should support the steps necessary to avoid unused bindings. Or, the BIRT runtime should be fixed in a way that when such an Exception is thrown, the report is still getting created.
I can imagine three possible solutions to fix that issue
1. When saving a report, bindings, which are bound in the 'Data Column Binding', but are not getting outputted somewhere, are removed from the 'Data Column Binding's.
1a. Alternatively the 'Refresh' button of the 'Binding' tab in the 'Property Editor View could do that job (what would be the opposite of what it is doing now)
1b. Adding a new Button that does the job.
2. The BIRT Runtime does not throw an exception as long as a bounded item is not used as output or as part of a script somewhere.
3. An easy to use API that makes it possible to update and refresh a report's dataset and bindings at runtime.
Could you please check which on of the solutions could be a possible solution, of check if there is another possible solution?
Thank you,
Jan
|
|
|
|
Re: Refresh Dataset using BIRT API [message #661921 is a reply to message #661553] |
Mon, 28 March 2011 14:21 |
|
Jan,
Not sure this is a option but there is an API command to remove unused
bindings. It can also be called in script. For example if I name a
table mytable, I can remove its unused bindings using the following
beforeFactory script.
reportContext.getDesignHandle().findElement("mytable").removedUnusedColumnBindings();
Jason
On 3/25/2011 5:52 AM, Jan Kohnert wrote:
> This is a example of a exception that results from bindings that are
> removed from the SQL Stored procedure's output (The field DEFICODE is no
> output!):
>
> The following items have errors:
>
> Table (id = 9): - Column binding "DEFICODE" has referred to a data set
> column "DEFICODE" which does not exist.
> data.engine.ColumnBindingReferToInexistColumn ( 1 time(s) )
> detail : org.eclipse.birt.report.engine.api.EngineException: Column
> binding "DEFICODE" has referred to a data set column "DEFICODE" which
> does not exist.
> at org.eclipse.birt.report.engine.executor.ExecutionContext.add
> Exception(ExecutionContext.java:1215)
> at org.eclipse.birt.report.engine.executor.ExecutionContext.add
> Exception(ExecutionContext.java:1179)
> at org.eclipse.birt.report.engine.executor.QueryItemExecutor.ex
> ecuteQuery(QueryItemExecutor.java:96)
> at org.eclipse.birt.report.engine.executor.TableItemExecutor.ex
> ecute(TableItemExecutor.java:62)
> at org.eclipse.birt.report.engine.internal.executor.dup.Suppres
> sDuplicateItemExecutor.execute(SuppressDuplicateItemExecutor .java:43)
> at org.eclipse.birt.report.engine.internal.executor.wrap.Wrappe
> dReportItemExecutor.execute(WrappedReportItemExecutor.java:4 6)
> at org.eclipse.birt.report.engine.internal.executor.l18n.Locali
> zedReportItemExecutor.execute(LocalizedReportItemExecutor.ja va:34)
> at org.eclipse.birt.report.engine.layout.html.HTMLBlockStacking
> LM.layoutNodes(HTMLBlockStackingLM.java:65)
> at org.eclipse.birt.report.engine.layout.html.HTMLPageLM.layout
> (HTMLPageLM.java:90)
> at org.eclipse.birt.report.engine.layout.html.HTMLReportLayoutE
> ngine.layout(HTMLReportLayoutEngine.java:99)
> at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.doR
> un(RunAndRenderTask.java:170)
> at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.run
> (RunAndRenderTask.java:75)
> at org.eclipse.birt.report.service.ReportEngineService.runAndRe
> nderReport(ReportEngineService.java:920)
> at org.eclipse.birt.report.service.BirtViewerReportService.runA
> ndRenderReport(BirtViewerReportService.java:973)
> at org.eclipse.birt.report.service.actionhandler.BirtGetPageAll
> ActionHandler.__execute(BirtGetPageAllActionHandler.java:131 )
> at org.eclipse.birt.report.service.actionhandler.AbstractBaseAc
> tionHandler.execute(AbstractBaseActionHandler.java:90)
> at org.eclipse.birt.report.soapengine.processor.AbstractBaseDoc
> umentProcessor.__executeAction(AbstractBaseDocumentProcessor .java:47)
> at org.eclipse.birt.report.soapengine.processor.AbstractBaseCom
> ponentProcessor.executeAction(AbstractBaseComponentProcessor .java:143)
> at org.eclipse.birt.report.soapengine.processor.BirtDocumentPro
> cessor.handleGetPageAll(BirtDocumentProcessor.java:183)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> at java.lang.reflect.Method.invoke(Unknown Source)
> at org.eclipse.birt.report.soapengine.processor.AbstractBaseCom
> ponentProcessor.process(AbstractBaseComponentProcessor.java: 112)
> at org.eclipse.birt.report.soapengine.endpoint.BirtSoapBindingI
> mpl.getUpdatedObjects(BirtSoapBindingImpl.java:66)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> at java.lang.reflect.Method.invoke(Unknown Source)
> at org.apache.axis.providers.java.RPCProvider.invokeMethod(RPCP
> rovider.java:397)
> at org.apache.axis.providers.java.RPCProvider.processMessage(RP
> CProvider.java:186)
> at org.apache.axis.providers.java.JavaProvider.invoke(JavaProvi
> der.java:323)
> at org.apache.axis.strategies.InvocationStrategy.visit(Invocati
> onStrategy.java:32)
> at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
> at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
> at org.apache.axis.handlers.soap.SOAPService.invoke(SOAPService .java:454)
> at org.apache.axis.server.AxisServer.invoke(AxisServer.java:281 )
> at org.apache.axis.transport.http.AxisServlet.doPost(AxisServle t.java:699)
> at org.eclipse.birt.report.servlet.BirtSoapMessageDispatcherSer
> vlet.doPost(BirtSoapMessageDispatcherServlet.java:265)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
> at org.apache.axis.transport.http.AxisServletBase.service(AxisS
> ervletBase.java:327)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
> at org.eclipse.birt.report.servlet.BirtSoapMessageDispatcherSer
> vlet.service(BirtSoapMessageDispatcherServlet.java:122)
> at org.eclipse.equinox.http.registry.internal.ServletManager$Se
> rvletWrapper.service(ServletManager.java:180)
> at org.eclipse.equinox.http.servlet.internal.ServletRegistratio
> n.handleRequest(ServletRegistration.java:90)
> at org.eclipse.equinox.http.servlet.internal.ProxyServlet.proce
> ssAlias(ProxyServlet.java:111)
> at org.eclipse.equinox.http.servlet.internal.ProxyServlet.servi
> ce(ProxyServlet.java:59)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
> at org.eclipse.equinox.http.jetty.internal.HttpServerManager$In
> ternalHttpServiceServlet.service(HttpServerManager.java:318)
> at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder .java:502)
> at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandl
> er.java:380)
> at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandl
> er.java:181)
> at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandl
> er.java:765)
> at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapp
> er.java:152)
> at org.mortbay.jetty.Server.handle(Server.java:324)
> at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnectio n.java:535)
> at org.mortbay.jetty.HttpConnection$RequestHandler.content(Http
> Connection.java:880)
> at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:748)
> at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java: 213)
> at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java: 404)
> at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEn
> dPoint.java:409)
> at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThr
> eadPool.java:520)
> Caused by: org.eclipse.birt.data.engine.core.DataException: Column
> binding "DEFICODE" has referred to a data set column "DEFICODE" which
> does not exist.
> at org.eclipse.birt.data.engine.impl.ResultIterator.validateMan
> ualBindingExpressions(ResultIterator.java:338)
> at
> org.eclipse.birt.data.engine.impl.ResultIterator.<init>(ResultIterator.java:141)
>
> at org.eclipse.birt.data.engine.impl.QueryResults.getResultIter
> ator(QueryResults.java:193)
> at org.eclipse.birt.report.engine.data.dte.QueryResultSet.<init
> >(QueryResultSet.java:98)
> at org.eclipse.birt.report.engine.data.dte.DteDataEngine.doExec
> uteQuery(DteDataEngine.java:168)
> at org.eclipse.birt.report.engine.data.dte.AbstractDataEngine.e
> xecute(AbstractDataEngine.java:265)
> at org.eclipse.birt.report.engine.executor.ExecutionContext.exe
> cuteQuery(ExecutionContext.java:1875)
> at org.eclipse.birt.report.engine.executor.QueryItemExecutor.ex
> ecuteQuery(QueryItemExecutor.java:80)
> ... 59 more
>
>
|
|
|
Re: Refresh Dataset using BIRT API [message #662306 is a reply to message #661921] |
Wed, 30 March 2011 08:24 |
Jan Kohnert Messages: 196 Registered: July 2009 |
Senior Member |
|
|
Jason,
thank you for that helpful peace of code!
In my runtime I can get the DesignElementHandle by calling:
design = getReportEngine().openReportDesign(file.getCanonicalPath());
DesignElementHandle element = design.getDesignHandle().getModuleHandle().findElement("???");
If I would know all DesignElementHandles of a IReportRunnable design, it would be easy to automatically remove the unused bindings when opening a report design.
DesignElementHandle[] elements = getAllElements(design);
for (int i = 0; i < elements.length; i++) {
if (elements[i] instanceof ReportItemHandle) {
ReportItemHandle reportItem = (ReportItemHandle) elements[i];
reportItem.removedUnusedColumnBindings();
}
}
Assuming that the method getAllElements(IReportRunnable design) would return a list of all DesignElementHandles.
Is there API available to get all that handles?
Thank you,
Jan
[Updated on: Wed, 30 March 2011 08:24] Report message to a moderator
|
|
|
Re: Refresh Dataset using BIRT API [message #662327 is a reply to message #657267] |
Wed, 30 March 2011 09:22 |
Jan Kohnert Messages: 196 Registered: July 2009 |
Senior Member |
|
|
I found a solution myself.
Module module = design.getDesignHandle().getModule();
List<DesignElement> allElements = module.getAllElements();
for (DesignElement designElement : allElements) {
DesignElementHandle handle = designElement.getHandle(module);
if (handle instanceof ReportItemHandle) {
ReportItemHandle reportItemHandle = (ReportItemHandle) handle;
reportItemHandle.removedUnusedColumnBindings();
}
}
[Updated on: Wed, 30 March 2011 09:23] Report message to a moderator
|
|
|
Re: Refresh Dataset using BIRT API [message #662410 is a reply to message #662327] |
Wed, 30 March 2011 14:55 |
|
Jan
This looks good. One note though. the removeUnusedColumnBindings
method does not check if you have referenced a binding in script. This
may not be an issue for you but then again..
Jason
On 3/30/2011 5:22 AM, Jan Kohnert wrote:
> I found a solution myself.
> Module module = design.getDesignHandle().getModule();
> List<DesignElement> allElements = module.getAllElements();
> for (DesignElement designElement : allElements) {
> DesignElementHandle handle = designElement.getHandle(module);
> if (handle instanceof ReportItemHandle) {
> ReportItemHandle reportItemHandle = (ReportItemHandle) handle;
> if (reportItemHandle != null){
> reportItemHandle.removedUnusedColumnBindings();
> }
> }
>
>
>
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04240 seconds