Jump to: navigation, search

Difference between revisions of "Seam (BIRT) Recipe"

m (Change project defaults)
m (Change project defaults)
 
(6 intermediate revisions by the same user not shown)
Line 71: Line 71:
 
** Change war target:
 
** Change war target:
 
<source lang="xml">
 
<source lang="xml">
<target name="war" depends="compile" description="Build the distribution .war file">
+
...
                <copy todir="${war.dir}">
+
<target name="war" depends="compile" description="Build the distribution .war file">            
                        <fileset dir="${basedir}/view" />
+
...
                        <fileset dir="${basedir}/resources">
+
    <copy todir="${war.dir}/WEB-INF/lib">
                                <include name="Reports/**/*" />
+
                        </fileset>
+
                </copy>
+
....
+
<copy todir="${war.dir}/WEB-INF/lib">
+
 
                         <fileset dir="${lib.dir}">
 
                         <fileset dir="${lib.dir}">
 
                                 <include name="richfaces-impl*.jar" />
 
                                 <include name="richfaces-impl*.jar" />
Line 90: Line 85:
 
                                 <exclude name="jboss-seam-gen.jar" />
 
                                 <exclude name="jboss-seam-gen.jar" />
 
                                 <!-- BIRT -->
 
                                 <!-- BIRT -->
                                <include name="seam-birt.jar" />
 
 
                                 <include name="com.ibm.icu_3.6.1.v20070906.jar" />
 
                                 <include name="com.ibm.icu_3.6.1.v20070906.jar" />
 
                                 <include name="commons-cli-1.0.jar" />
 
                                 <include name="commons-cli-1.0.jar" />
Line 120: Line 114:
 
== Code Seam-BIRT servlet ==
 
== Code Seam-BIRT servlet ==
 
* Make two new classes in the project (e.g. in <code>$PROJECT/src/action</code> dir)
 
* Make two new classes in the project (e.g. in <code>$PROJECT/src/action</code> dir)
** org.jboss.seam.pdf.birt.BirtEngine
+
** org.jboss.seam.pdf.birt.BirtEngine - see [[Seam (BIRT) Recipe - BirtEngine]]
<source lang="java">
+
** org.jboss.seam.pdf.birt.DocumentStoreServlet - see [[Seam (BIRT) Recipe - DocumentStoreServlet]]
package org.jboss.seam.pdf.birt;
+
  
import java.io.IOException;
+
* Add BIRT pdf servlet to $PROJECT/resources/WEB-INF/web.xml .
import java.io.InputStream;
+
import java.util.Properties;
+
import java.util.logging.Level;
+
 
+
import javax.servlet.ServletContext;
+
 
+
import org.eclipse.birt.core.exception.BirtException;
+
import org.eclipse.birt.core.framework.IPlatformContext;
+
import org.eclipse.birt.core.framework.Platform;
+
import org.eclipse.birt.core.framework.PlatformServletContext;
+
import org.eclipse.birt.report.engine.api.EngineConfig;
+
import org.eclipse.birt.report.engine.api.IReportEngine;
+
import org.eclipse.birt.report.engine.api.IReportEngineFactory;
+
 
+
public class BirtEngine {
+
 
+
private static IReportEngine birtEngine = null;
+
 
+
private static Properties configProps = new Properties();
+
 
+
private final static String configFile = "BirtConfig.properties";
+
 
+
public static synchronized void initBirtConfig() {
+
loadEngineProps();
+
}
+
 
+
public static synchronized IReportEngine getBirtEngine(ServletContext sc) {
+
if (birtEngine == null) {
+
EngineConfig config = new EngineConfig();
+
if (configProps != null) {
+
String logLevel = configProps.getProperty("logLevel");
+
Level level = Level.OFF;
+
if ("SEVERE".equalsIgnoreCase(logLevel)) {
+
level = Level.SEVERE;
+
} else if ("WARNING".equalsIgnoreCase(logLevel)) {
+
level = Level.WARNING;
+
} else if ("INFO".equalsIgnoreCase(logLevel)) {
+
level = Level.INFO;
+
} else if ("CONFIG".equalsIgnoreCase(logLevel)) {
+
level = Level.CONFIG;
+
} else if ("FINE".equalsIgnoreCase(logLevel)) {
+
level = Level.FINE;
+
} else if ("FINER".equalsIgnoreCase(logLevel)) {
+
level = Level.FINER;
+
} else if ("FINEST".equalsIgnoreCase(logLevel)) {
+
level = Level.FINEST;
+
} else if ("OFF".equalsIgnoreCase(logLevel)) {
+
level = Level.OFF;
+
}
+
 
+
config.setLogConfig(configProps.getProperty("logDirectory"),
+
level);
+
}
+
 
+
config.setEngineHome("");
+
IPlatformContext context = new PlatformServletContext(sc);
+
config.setPlatformContext(context);
+
 
+
try {
+
Platform.startup(config);
+
} catch (BirtException e) {
+
e.printStackTrace();
+
}
+
 
+
IReportEngineFactory factory = (IReportEngineFactory) Platform
+
.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
+
birtEngine = factory.createReportEngine(config);
+
 
+
}
+
return birtEngine;
+
}
+
 
+
public static synchronized void destroyBirtEngine() {
+
if (birtEngine == null) {
+
return;
+
}
+
birtEngine.shutdown();
+
Platform.shutdown();
+
birtEngine = null;
+
}
+
 
+
public Object clone() throws CloneNotSupportedException {
+
throw new CloneNotSupportedException();
+
}
+
 
+
private static void loadEngineProps() {
+
try {
+
// Config File must be in classpath
+
ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
InputStream in = null;
+
in = cl.getResourceAsStream(configFile);
+
configProps.load(in);
+
in.close();
+
 
+
} catch (IOException e) {
+
e.printStackTrace();
+
}
+
 
+
}
+
 
+
}
+
</source>
+
** org.jboss.seam.pdf.birt.DocumentStoreServlet
+
<source lang="java">
+
package org.jboss.seam.pdf.birt;
+
 
+
import java.io.IOException;
+
 
+
public class DocumentStoreServlet extends HttpServlet {
+
protected IReportEngine engine;
+
protected IFragment requester;
+
 
+
private static final long serialVersionUID = 519600274155718202L;
+
 
+
public void init(ServletConfig servletconfig) throws ServletException {
+
super.init(servletconfig);
+
BirtEngine.initBirtConfig();
+
}
+
 
+
@Override
+
protected void doGet(final HttpServletRequest request,
+
final HttpServletResponse response) throws ServletException,
+
IOException {
+
 
+
new ContextualHttpServletRequest(request) {
+
@Override
+
public void process() throws ServletException, IOException {
+
try {
+
executeReport( request, response);
+
} catch (EngineException e) {
+
log("executeReport error", e);
+
}
+
 
+
}
+
}.run();
+
 
+
}
+
 
+
 
+
void executeReport(HttpServletRequest request, HttpServletResponse response) throws EngineException {
+
 
+
        //resp.setContentType("text/html");
+
        response.setContentType( "application/pdf" );
+
        response.setHeader ("Content-Disposition","inline; filename=test.pdf");         
+
        String reportName = request.getServletPath();
+
        ServletContext sc = request.getSession().getServletContext();
+
        this.engine = BirtEngine.getBirtEngine(sc);
+
       
+
       
+
        IReportRunnable design;
+
        try
+
        {
+
                //Open report design
+
      design = engine.openReportDesign( sc.getRealPath("./")+reportName.substring(0, reportName.length() -4) + ".xhtml" );
+
                //create task to run and render report
+
                IRunAndRenderTask task = engine.createRunAndRenderTask( design );           
+
                task.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY, DocumentStoreServlet.class.getClassLoader());
+
                //set output options
+
                //HTMLRenderOption options = new HTMLRenderOption();
+
                PDFRenderOption options = new PDFRenderOption();
+
                //options.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_HTML);
+
                options.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_PDF);
+
                options.setOutputStream(response.getOutputStream());
+
                //options.setBaseImageURL(req.getContextPath()+"/images");
+
                //options.setImageDirectory(sc.getRealPath("/images"));
+
                task.setRenderOption(options);
+
               
+
                //run report
+
                task.run();
+
                task.close();
+
        }catch (IOException e){
+
               
+
                e.printStackTrace();
+
                return;
+
        }
+
 
+
 
+
System.out.println("Finished");
+
}
+
 
+
/**
+
* Destruction of the servlet.
+
 
+
*/
+
public void destroy() {
+
super.destroy();
+
BirtEngine.destroyBirtEngine();
+
}
+
}
+
</source>
+
* Add BIRT pdf servlet to $PROJECT/resources/WEB-INF/web.xml (see attached web.xml).
+
 
<source lang="xml">
 
<source lang="xml">
 
....
 
....
Line 330: Line 132:
 
...
 
...
 
</source>
 
</source>
 +
 
== Make BIRT report ==
 
== Make BIRT report ==
 
* make <code>$PROJECT/view/sample.xhtml</code> report (rptdesign)
 
* make <code>$PROJECT/view/sample.xhtml</code> report (rptdesign)
Line 339: Line 142:
 
...
 
...
 
</source>
 
</source>
sample.xhtml all in one:
+
sample.xhtml all in one: [[Seam (BIRT) Recipe - Sample Report]]
<source lang="xml">
+
<?xml version="1.0" encoding="UTF-8"?>
+
<report xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.15" id="1">
+
    <property name="createdBy">Eclipse BIRT Designer Version 2.2.1.r221_v20070924 Build &lt;2.2.0.v20070924-1550></property>
+
    <property name="units">in</property>
+
    <data-sources>
+
        <script-data-source name="CustomersFavorite" id="2"/>
+
    </data-sources>
+
    <data-sets>
+
        <script-data-set name="Favorite" id="3">
+
            <list-property name="resultSetHints">
+
                <structure>
+
                    <property name="position">1</property>
+
                    <property name="name">Name</property>
+
                    <property name="dataType">any</property>
+
                </structure>
+
                <structure>
+
                    <property name="position">2</property>
+
                    <property name="name">Version</property>
+
                    <property name="dataType">any</property>
+
                </structure>
+
                <structure>
+
                    <property name="position">3</property>
+
                    <property name="name">Id</property>
+
                </structure>
+
            </list-property>
+
            <list-property name="columnHints">
+
                <structure>
+
                    <property name="columnName">Name</property>
+
                </structure>
+
                <structure>
+
                    <property name="columnName">Version</property>
+
                </structure>
+
                <structure>
+
                    <property name="columnName">Id</property>
+
                </structure>
+
            </list-property>
+
            <structure name="cachedMetaData">
+
                <list-property name="resultSet">
+
                    <structure>
+
                        <property name="position">1</property>
+
                        <property name="name">Name</property>
+
                        <property name="dataType">any</property>
+
                    </structure>
+
                    <structure>
+
                        <property name="position">2</property>
+
                        <property name="name">Version</property>
+
                        <property name="dataType">any</property>
+
                    </structure>
+
                    <structure>
+
                        <property name="position">3</property>
+
                        <property name="name">Id</property>
+
                        <property name="dataType">any</property>
+
                    </structure>
+
                </list-property>
+
            </structure>
+
            <property name="dataSource">CustomersFavorite</property>
+
            <method name="open"><![CDATA[var reports = Packages.org.jboss.seam.Component.getInstance("sampleReportList", true);
+
            reportsIterator = reports.getResultList().listIterator();]]></method>
+
            <method name="fetch"><![CDATA[if( !( reportsIterator.hasNext()) ){
+
return( false );
+
}
+
 
+
var report = reportsIterator.next();
+
 
+
row["Name"] = report.name;
+
row["Version"] = report.version;
+
row["Id"] = new Packages.java.lang.Integer(report.id);
+
 
+
return ( true );]]></method>
+
            <method name="close"><![CDATA[reportsIterator = null;]]></method>
+
        </script-data-set>
+
    </data-sets>
+
    <page-setup>
+
        <simple-master-page name="Simple Master Page" id="4">
+
            <page-footer>
+
                <text id="5">
+
                    <property name="contentType">html</property>
+
                    <text-property name="content"><![CDATA[<value-of>new Date()</value-of>]]></text-property>
+
                </text>
+
            </page-footer>
+
        </simple-master-page>
+
    </page-setup>
+
    <body>
+
        <label id="46">
+
            <property name="textAlign">center</property>
+
            <text-property name="text">Sample Report</text-property>
+
        </label>     
+
        <table id="19">
+
            <property name="width">100%</property>
+
            <property name="dataSet">Favorite</property>
+
            <list-property name="boundDataColumns">
+
                <structure>
+
                    <property name="name">Name</property>
+
                    <expression name="expression">dataSetRow["Name"]</expression>
+
                </structure>
+
                <structure>
+
                    <property name="name">Version</property>
+
                    <expression name="expression">dataSetRow["Version"]</expression>
+
                </structure>
+
                <structure>
+
                    <property name="name">Id</property>
+
                    <expression name="expression">dataSetRow["Id"]</expression>
+
                </structure>
+
            </list-property>
+
            <column id="22">
+
                <property name="width">0.7368421053in</property>
+
            </column>
+
            <column id="20">
+
                <property name="width">1.458in</property>
+
                <property name="repeat">1</property>
+
            </column>
+
            <header>
+
                <row id="23">
+
                    <property name="backgroundColor">#FF8040</property>
+
                    <cell id="28">
+
                        <label id="29">
+
                            <property name="backgroundColor">#FF8040</property>
+
                            <text-property name="text">Id</text-property>
+
                        </label>
+
                    </cell>
+
                    <cell id="24">
+
                        <label id="25">
+
                            <property name="backgroundColor">#FF8040</property>
+
                            <text-property name="text">Name</text-property>
+
                        </label>
+
                    </cell>
+
                </row>
+
            </header>
+
            <detail>
+
                <row id="30">
+
                    <list-property name="highlightRules">
+
                        <structure>
+
                            <property name="operator">eq</property>
+
                            <property name="backgroundColor">#E4B07C</property>
+
                            <property name="color">#000000</property>
+
                            <expression name="testExpr">row[0]%2</expression>
+
                            <expression name="value1">0</expression>
+
                        </structure>
+
                    </list-property>
+
                    <cell id="35">
+
                        <data id="36">
+
                            <property name="resultSetColumn">Id</property>
+
                        </data>
+
                    </cell>
+
                    <cell id="31">
+
                        <data id="32">
+
                            <property name="resultSetColumn">Name</property>
+
                        </data>
+
                    </cell>
+
                </row>
+
            </detail>
+
            <footer>
+
                <row id="37">
+
                    <cell id="40"/>
+
                    <cell id="38"/>
+
                </row>
+
            </footer>
+
        </table>
+
    </body>
+
</report>
+
</source>
+
  
** Add create report button to <code>$PROJECT/view/sampleReportList.xhtml</code>
+
** Add create report button to <code>$PROJECT/view/sampleReportList.xhtml</code> [[Seam (BIRT) Recipe - sampleReportList.xhtml]]
 
<source lang="xml">
 
<source lang="xml">
 
...
 
...
Line 518: Line 159:
 
* Run <code>ant explode</code>, start jBoss app. server
 
* Run <code>ant explode</code>, start jBoss app. server
 
* Cook in oven about 40 minutes & visit [http://localhost:8080/seambirt restaurant] :-)
 
* Cook in oven about 40 minutes & visit [http://localhost:8080/seambirt restaurant] :-)
 +
 +
----
 +
[[Image:seambirt-seam.png|frame|Seam app UI]]
 +
[[Image:seambirt-birt.png|frame|Seam component in BIRT]]

Latest revision as of 02:02, 18 June 2008

Set up environment

Get started with Seam

#Generated by seam setup
#Sun May 11 07:49:04 CEST 2008
hibernate.connection.password=
workspace.home=/home/user/projects
model.package=org.seambirt.sample.entity
driver.jar=lib/hsqldb.jar
action.package=org.seambirt.sample
test.package=org.seambirt.sample.test
database.type=hsql
richfaces.skin=deepMarine
hibernate.default_catalog.null=
hibernate.default_schema.null=
database.drop=n
project.name=seambirt
hibernate.connection.username=sa
hibernate.connection.driver_class=org.hsqldb.jdbcDriver
hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
project.type=ear
icefaces.home=
database.exists=n
jboss.home=/opt/jboss-4.2.2.GA
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.connection.url=jdbc\:hsqldb\:.
  • Generate new entity ($ seam new-entity). I named it SampleReport.
  • [OPTIONAL] Include Seam project into your IDE. Eclipse Users: Add the project

into Eclipse using File > New > Project and select General > Project (not Java Project). NetBeans Users: Open the project in NetBeans.

Get started with BIRT

cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/com.ibm.icu_3.6.1.v20070906.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/commons-cli-1.0.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/coreapi.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/dataadapterapi.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/dteapi.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/engineapi.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/flute.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/chartengineapi.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/js.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/modelapi.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/modelodaapi.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/odadesignapi.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/org.apache.commons.codec_1.3.0.v200706111738.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/org.eclipse.emf.common_2.2.1.v200702131851.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/org.eclipse.emf.ecore.xmi_2.2.2.v200702131851.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/org.eclipse.emf.ecore_2.2.2.v200702131851.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/org.w3c.css.sac_1.3.0.v200706111724.jar $PROJECT/lib
cp $BIRT_RUNTIME/WebViewerExample/WEB-INF/lib/scriptapi.jar $PROJECT/lib
  • Copy dir (include subdirs) from $BIRT_RUNTIME/WebViewerExample/WEB-INF/platform to $PROJECT/resources/WEB-INF/platform
cp -r $BIRT_RUNTIME/WebViewerExample/WEB-INF/platform $PROJECT/resources/WEB-INF/platform

Integrate

Change project defaults

  • Change ant script $PROJECT/build.xml
    • Add property
<property name="birt.platform.dir" value="resources/WEB-INF/platform" />
    • Change war target:
...
<target name="war" depends="compile" description="Build the distribution .war file">             
...
    <copy todir="${war.dir}/WEB-INF/lib">
                        <fileset dir="${lib.dir}">
                                <include name="richfaces-impl*.jar" />
                                <include name="richfaces-ui*.jar" />
                                <include name="oscache*.jar" />
                                <include name="commons-digester.jar" />
                                <include name="commons-beanutils.jar" />
                                <include name="jsf-facelets.jar" />
                                <include name="jboss-seam-*.jar" />
                                <exclude name="jboss-seam-gen.jar" />
                                <!-- BIRT -->
                                <include name="com.ibm.icu_3.6.1.v20070906.jar" />
                                <include name="commons-cli-1.0.jar" />
                                <include name="coreapi.jar" />
                                <include name="dataadapterapi.jar" />
                                <include name="dteapi.jar" />
                                <include name="engineapi.jar" />
                                <include name="flute.jar" />
                                <include name="chartengineapi.jar" />
                                <include name="js.jar" />
                                <include name="modelapi.jar" />
                                <include name="modelodaapi.jar" />
                                <include name="odadesignapi.jar" />
                                <include name="org.apache.commons.codec_1.3.0.v200706111738.jar" />
                                <include name="org.eclipse.emf.common_2.2.1.v200702131851.jar" />
                                <include name="org.eclipse.emf.ecore.xmi_2.2.2.v200702131851.jar" />
                                <include name="org.eclipse.emf.ecore_2.2.2.v200702131851.jar" />
                                <include name="org.w3c.css.sac_1.3.0.v200706111724.jar" />
                                <include name="scriptapi.jar" />
                        </fileset>
                </copy>
                <copy todir="${war.dir}/WEB-INF/platform/">
                        <fileset dir="${birt.platform.dir}" />
                </copy>

build.xml all in one: Seam (BIRT) Recipe - $PROJECT/build.xml

Code Seam-BIRT servlet

  • Add BIRT pdf servlet to $PROJECT/resources/WEB-INF/web.xml .
....
  <!--  BIRT PDF servlet -->
   <servlet>
        <servlet-name>Document Store Servlet</servlet-name>
        <servlet-class>org.jboss.seam.pdf.birt.DocumentStoreServlet</servlet-class>
    </servlet>
 
    <servlet-mapping>
        <servlet-name>Document Store Servlet</servlet-name>
        <url-pattern>*.pdf</url-pattern>
    </servlet-mapping>
...

Make BIRT report

  • make $PROJECT/view/sample.xhtml report (rptdesign)

Instantiate Seam component by

...
            <method name="open"><![CDATA[var reports = Packages.org.jboss.seam.Component.getInstance("sampleReportList", true);
            reportsIterator = reports.getResultList().listIterator();]]></method>
...

sample.xhtml all in one: Seam (BIRT) Recipe - Sample Report

...
<div class="actionButtons">
        <s:button id="done" 
               value="Create sampleReport"
                view="/sampleReport.xhtml"/>	
        <s:button id="report" value="Report" view="/sample.pdf?ReportName=report.rptdesign" />		  
</div>
...

Bon appetit

  • Run ant explode, start jBoss app. server
  • Cook in oven about 40 minutes & visit restaurant :-)

Seam app UI
Seam component in BIRT