在Jboss portal 上开发birt
谁知道在wordpress 下只用syntax 插件之后使用<pre lang=”xml”> 为什么xml 展现不正确,请留言告知.
java 的portal 技术在展现上还是具有非常大的优势的,虽然jsr 268 并没能完全统一各portal 之间的不标准性. 但是在portal 上开发展现的东西还是非常有意思的,尤其是dnd (拖拽portlet) 和partial refresh (也可以定时自动部分刷新) 特性还是非常华丽的.
BIRT 作为最好的报表框架,对于分析展现数据具有很大优势,这篇文章就解释一下如何在jboss portal 上部署birt . 在官方的birt wiki 上有一篇介绍portal 上部署birt 的,不过那个文章太老了,基于birt 2.1 的, 尤其是它的portal 容器是apache pluto , 里面还有pluto 专有的api . 这篇文章介绍的是通用portal api. 只不过特定部署在jboss portal 上,如果你想要部署在其他portal 容器也可以,修改一下portal 的部署描述符就够了,代码不用改.
ok, let’s start
任何birt 要运行起来首先要实例化一个BirtEngine (org.eclipse.birt.report.engine.api.IReportEngine) , 所以首先还是写一个util 类, 用来取得BirtEngine.
import java.util.logging.Level; import javax.portlet.PortletContext; import org.eclipse.birt.report.engine.api.EngineConfig; import org.eclipse.birt.report.engine.api.IReportEngine; import org.eclipse.birt.core.framework.Platform; import org.eclipse.birt.core.exception.BirtException; import org.eclipse.birt.report.engine.api.IReportEngineFactory; public class BirtEngine { private static IReportEngine birtEngine = null; public static synchronized IReportEngine getBirtEngine(PortletContext pc) { if (birtEngine == null) { EngineConfig config = new EngineConfig(); config.setLogConfig("D:/birt", Level.FINEST); config.setEngineHome("E:/java/birt/birt-runtime-2_3_2/birt-runtime-2_3_2/ReportEngine/"); //IPlatformContext context = new PlatformPortletContext(pc); //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.destroy(); Platform.shutdown(); birtEngine = null; }
import java.util.logging.*; import javax.portlet.*; import java.io.IOException; //+++++++++++++BIRT import org.eclipse.birt.report.engine.api.IReportEngine; import org.eclipse.birt.report.engine.api.HTMLRenderOption; import org.eclipse.birt.report.engine.api.IReportRunnable; import org.eclipse.birt.report.engine.api.IRunAndRenderTask; import org.eclipse.birt.report.engine.api.HTMLServerImageHandler; public class JbossBirtPortlet extends GenericPortlet { private static final long serialVersionUID = 1L; /** * Constructor of the object. */ private IReportEngine birtReportEngine = null; protected static Logger logger = Logger.getLogger("org.eclipse.birt"); public JbossBirtPortlet() { super(); } /** * Destruction of the portlet. */ public void destroy() { super.destroy(); BirtEngine.destroyBirtEngine(); } protected void doView(RenderRequest rRequest, RenderResponse rResponse) throws PortletException, IOException, UnavailableException { rResponse.setContentType("text/html"); this.birtReportEngine = BirtEngine.getBirtEngine(rRequest .getPortletSession().getPortletContext()); IReportRunnable design; try { // Open report design design = this.birtReportEngine.openReportDesign(rRequest .getPortletSession().getPortletContext().getRealPath( "/reports/a.rptdesign")); // create task to run and render report IRunAndRenderTask task = birtReportEngine .createRunAndRenderTask(design); // set output options HTMLRenderOption options = new HTMLRenderOption(); options.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_HTML); options.setImageHandler(new HTMLServerImageHandler()); options.setOutputStream(rResponse.getPortletOutputStream()); options.setBaseImageURL(rRequest.getContextPath() + "/images"); options.setImageDirectory(rRequest.getPortletSession() .getPortletContext().getRealPath("/images")); task.setRenderOption(options); // run report task.run(); task.close(); } catch (Exception e) { e.printStackTrace(); throw new javax.portlet.PortletException(e); } } /** * Initialization of the portlet. * * @throws PortletException * if an error occure */ public void init() throws javax.portlet.PortletException { } }
通用的 portal 描述文件 portlet.xml
<?xml version="1.0" encoding="UTF-8"?> <portlet -app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"> </portlet><portlet> </portlet><portlet -name>JbossBirtPortlet</portlet> <portlet -class>a.JbossBirtPortlet</portlet> <supports> <mime -type>text/html</mime> <portlet -mode>VIEW</portlet> </supports> <portlet -info> </portlet>
描述jbossbirt-object.xml 名字可以随便叫,对应一个自定义的portal 就行了
<?xml version="1.0" encoding="UTF-8"?> <deployments> <deployment> <if -exists>overwrite</if> <parent -ref>default.mysql</parent> <context> </context><context -name>dashboard</context> <properties> <property> <name>theme.dyna.partial_refresh_enabled </name> <value>true</value> </property> <property> <name>theme.dyna.dnd_enabled</name> <value>true</value> </property> </properties> <supported -mode> <mode>view</mode> <mode>edit</mode> <mode>help</mode> </supported> <window> </window><window -name>JbossBirtPortletWindow </window> <instance -ref>JbossBirtPortletInstance </instance> <region>center</region> <height>1</height> </deployment> </deployments>
单个portal instance 的定义 portlet-instances.xml
<?xml version="1.0" standalone="yes"?> <deployments> <deployment> <instance> </instance><instance -id>JbossBirtPortletInstance </instance> <portlet -ref>JbossBirtPortlet</portlet> </deployment> <preferences> <preference> <name>abc</name> <value>def</value> </preference> </preferences> </deployments>
单个portal 当然也需要web.xml 描述符,如果你没使用任何servlet,listerner,filter 的话,留空就行了
<?xml version="1.0" encoding="UTF-8"?> <web -app xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" />
上述代码中最奇怪的算是
config.setEngineHome("E:/java/birt/birt-runtime-2_3_2/birt-runtime-2_3_2/ReportEngine/");
这是因为在jboss portal 里面没有办法取到ServletContext 对象,jboss portal 是跟jboss 绑定的, 其他的一些portal 容器一般都跟应用容器无关, 像是liferay, jetspeed 等基本都可以部署到jetty,tomcat等任意java应用容器, 其他容器都可以取到ServletContext 对象,(一般都是从RenderRequest 里面). 所以只好把birt engine 的位置放在一个操作系统上的绝对位置. 部署的时候需要包括birt runtime 下面的lib 包放在这个portal 的WEB-INF/lib 下 ,但是不需要platform 或者plugin 下的其他包, 你的EngineHome 设置的是正确的就行了. 如果泥启动的时候遇到了can’t startup osgi platform xxx , 就证明目录有问题. 确保是设置在birt runtime 下面的reportengine 目录下.
http://birtworld.blogspot.com/2008_08_01_archive.html
另一篇关于如何在jboss portal 上部署birt 的文章, 使用的是PlatformContext 方法,不过我没运行起来,jboss 总是指向一个它运行时候的临时目录,newsgroup 上也讨论了这个问题,最后还是设置的绝对目录.
如果本身需要把birt 集成到rcp , 或者一个什么特定的servlet 容器环境下,这种自定义PlatformContext 的方法还是值得参考的, 但如果没运行起来,绝对目录的方法最简单.
还是建议不要使用jboss portal 比较好,现在觉得apache 的jetspeed 不错,够轻量级. 还支持maven.
警告: 本文在jboss portal 2.6.8 上测试通过,并且确定与2.7.2 不兼容.
写这篇文章的目的是在做一个使用portal 与birt 集成的监控系统,主要面向多台主机的复杂环境,不做数据收集,只做数据展现. 放在
http://code.google.com/p/portal-monitor/
现在还什么都没有. 估计会选用jetspeed , birt 主要监控mysql , oracle , 会参考oracle 的OEM 和 cacti-mysql-template (percona 那个,cacti 报表的那个版本控制简直是要人命). 其他的比如jboss , jvm , memcache 说不定哪天抄其他人的代码也弄一个的.
参考资料:
http://birtworld.blogspot.com/2008_08_01_archive.html
http://www.birt-exchange.com/devshare/deploying-birt-reports/460-jboss-birt-portlet/
Hi,您好,我是一个birt的初学者,我想了解下用birt这样的开源工具能不能制作dashboard,我看到actuate的Dashboard做的很漂亮。
看你怎么定义dashboard 了,如果有很复杂的布局什么的,单单birt做不了. 如果只是简单的就看你需求是怎么样的.
博主: 最近, 怎么没有更新博客啊? 你的知识面挺广, 希望能交流交流.