首页 > BIRT > 在Jboss portal 上开发birt

在Jboss portal 上开发birt

2009年4月15日 发表评论 阅读评论

谁知道在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(&quot;D:/birt&quot;, Level.FINEST);
			config.setEngineHome(&quot;E:/java/birt/birt-runtime-2_3_2/birt-runtime-2_3_2/ReportEngine/&quot;);
			//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(&quot;org.eclipse.birt&quot;);
 
	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(&quot;text/html&quot;);
		this.birtReportEngine = BirtEngine.getBirtEngine(rRequest
				.getPortletSession().getPortletContext());
 
		IReportRunnable design;
		try {
			// Open report design
			design = this.birtReportEngine.openReportDesign(rRequest
					.getPortletSession().getPortletContext().getRealPath(
							&quot;/reports/a.rptdesign&quot;));
			// 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() + &quot;/images&quot;);
			options.setImageDirectory(rRequest.getPortletSession()
					.getPortletContext().getRealPath(&quot;/images&quot;));
 
			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

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
<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 就行了

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
<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

&lt;?xml version=&quot;1.0&quot; standalone=&quot;yes&quot;?&gt;
<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 的话,留空就行了

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
<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/

分类: BIRT 标签: , , ,
  1. miketian
    2009年9月22日19:20 | #1

    Hi,您好,我是一个birt的初学者,我想了解下用birt这样的开源工具能不能制作dashboard,我看到actuate的Dashboard做的很漂亮。

  2. 2009年10月8日01:25 | #2

    看你怎么定义dashboard 了,如果有很复杂的布局什么的,单单birt做不了. 如果只是简单的就看你需求是怎么样的.

  1. 本文目前尚无任何 trackbacks 和 pingbacks.