Bug 342836 - Save rptdocument to an OutputStream: IRunTask interface
Summary: Save rptdocument to an OutputStream: IRunTask interface
Status: NEW
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: BIRT (show other bugs)
Version: 2.6.2   Edit
Hardware: PC Windows XP
: P3 enhancement (vote)
Target Milestone: Future   Edit
Assignee: Birt-ReportEngine-inbox@eclipse.org CLA
QA Contact:
URL:
Whiteboard:
Keywords: api
Depends on:
Blocks:
 
Reported: 2011-04-14 09:50 EDT by Simone Pulcini CLA
Modified: 2011-04-15 05:40 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Simone Pulcini CLA 2011-04-14 09:50:15 EDT
Build Identifier: Eclipse 20110301-1815. Birt DE API 2.6.2

At the moment IRunTask does not offer an easy way to obtain an rptdocument on a Stream, at least not direct as IRenderTaks implementation using HTMLRenderOption class. I hope that in future version Birt developers can provide via API a similar mechanism to stream the rptdocument file. I understand that the structure of the rptdocument is somewhat complex (it's a binary format, it's compressed and the abstraction to interact with it's to manage an archive with contenents and dirs).
But my need it's easy than interact with the file. I need the stream just to store it on a BLOB column on db to avoid a file storage (I need to control the cache using a db instead of a storage). Storing the output format in HTML, PDF and XLS is less convenient than storing the intermediate format itself.

Reproducible: Always
Comment 1 Wei Yan CLA 2011-04-14 13:02:19 EDT
A workaround is saving the report document into a local file then uploading it to the database. The document should be downloaded as a local file before rendering. Your application may implement a document caching layer to manager the document downloading.
Comment 2 Simone Pulcini CLA 2011-04-14 13:51:35 EDT
(In reply to comment #1)
> A workaround is saving the report document into a local file then uploading it
> to the database. The document should be downloaded as a local file before
> rendering. Your application may implement a document caching layer to manager
> the document downloading.

This is a good solution but I need to implement a mechanism to limit disk storage. I also need to "bind" file presence to db transaction: file can't be destroyed by cache mechanism if it has not been yet stored on the BLOB. Using a stream it's easy because of its liveness inside memory: destruction is done bye garbage collector. Also I can use the stream directly to push the output to the browser client.
Comment 3 Wei Yan CLA 2011-04-14 14:09:51 EDT
You can implement a in memory IArchiveFile and use that in memory archive to create/rendering document.

You can see the org.eclipse.birt.core.archive.compound.IArchiveFile. For example, 

class MemoryArchive implements IArchiveFile {
   MemoryArchive(int sizeLimit); //throws out exception if exceed the size limitation
   MemoryArchive(byte[] source);
   byte[] getBytes();
}

//Running
MemoryArchive archive = new MemoryArchive(sizeLimit);
IRunTask task = engine.createRunTask();
task.run(new ArchiveWriter(archive));
task.close9);
byte[] bytes = archive.getBytes();
//upload the bytes to the database..

//Rendering
byte[] bytes; //download from the database
MemoryArchive archive = new MemoryArchive(bytes);
IReportDocument document = engine.openReportDocument(archive);
RenderTask task = engine.createRenderTask(document);
task.render()
...
Comment 4 Simone Pulcini CLA 2011-04-15 05:17:13 EDT
(In reply to comment #3)
> You can implement a in memory IArchiveFile and use that in memory archive to
> create/rendering document.
> You can see the org.eclipse.birt.core.archive.compound.IArchiveFile. For
> example, 
> class MemoryArchive implements IArchiveFile {
>    MemoryArchive(int sizeLimit); //throws out exception if exceed the size
> limitation
>    MemoryArchive(byte[] source);
>    byte[] getBytes();
> }
> //Running
> MemoryArchive archive = new MemoryArchive(sizeLimit);
> IRunTask task = engine.createRunTask();
> task.run(new ArchiveWriter(archive));
> task.close9);
> byte[] bytes = archive.getBytes();
> //upload the bytes to the database..
> //Rendering
> byte[] bytes; //download from the database
> MemoryArchive archive = new MemoryArchive(bytes);
> IReportDocument document = engine.openReportDocument(archive);
> RenderTask task = engine.createRenderTask(document);
> task.render()
> ...

Sounds great! I'm coding :-) Should I risk something providing empty implementations for other method signatures in IArchiveFile interface? Btw thanks a lot for this workaround. It's my fault I do not understand the javadoc in details.
Comment 5 Simone Pulcini CLA 2011-04-15 05:40:25 EDT
This is the signature of openReportDocument

public IReportDocument openReportDocument(java.lang.String systemId,       org.eclipse.birt.core.archive.IDocArchiveReader reader,java.util.Map options)
                                   throws EngineException

Call to this method in your code snippet is a bit different. I've got the second parameter, the first maybe null.... but I've got no idea about the options Map). Can it be null in my case?