使用EclipseBIRT扩展点:聚合

简介:了解 BIRT 扩展点模型,使用新的 V2.3+ 扩展模型在 BIRT 中创建基 本聚合扩展。

本文介绍商业智能和报告工具(Business Intelligence and Reporting Tools,BIRT)扩展点模型,并在 BIRT V2.3.x 和 V2.5.x 中实际创建一个聚合 扩展。在较早的 BIRT 版本中,创建聚合扩展的方式是扩展 org.eclipse.birt.data.aggregation 扩展点,这会在一个名为 Total 的全局对 象中添加一个小函数,您可以在整个报告的任何表达式中使用该函数,其工作原 理类似于脚本函数扩展点。

但是,从 BIRT V2.2 到 V2.3,聚合扩展已经发生了变化。新的方式更加复杂 ,但可以在 Aggregation Widgets 下拉列表中得到一个不错的聚合,还为参数和 表达式提供了漂亮的文本框。当创建此扩展时,可以在您的表中以列绑定的形式 访问结果。

从总体上看,新的聚合扩展点包含一个对象,该对象是 IAggregationFacTory 接口的扩展。可以在此接口中重载方法来完成 3 项操作:

初始化您的工厂(在构造函数中)

提供由工厂提供的一组聚合(以列表形式提供,包含聚合对象的实际实例)

返回聚合对象的单一实例

聚合的每个实例都需要实现 IAggrFunction 接口。需要实现许多含义明显的 方法,比如 getName、getDataType 和 getParmaeterDefn,还需要实现其他含义 不太明显的方法。例如,getNumberOfPasses() 和 getType() 方法是相关的。 getType() 方法制定此聚合器的执行方式和类型。有两种聚合类型: SUMMARY_AGGR 表示只为摘要计算该聚合(比如表的表头或表尾),RUNNING_AGGR 表示为表中的每一行或表尾计算聚合。getNumberOfPasses() 方法显示获得结果 所需的 pass 数。所有基于评级的聚合器,比如 TopNpercent、PercentSum 和 Percentile,都会返回值 2,其余聚合器返回值 1。

IAggrFunction 接口的实际实现必须返回其 newAccumulaTor() 方法中的 AccumulaTor 类的一个扩展。AccumulaTor 负责执行实际的计算。有一些默认方 法需要重载,最重要的是 onRow(),表中的每一行都需要调用该方法。使用此方 法,您可以解析函数的参数并执行计算。对于 SUM,可以添加到某个已存储的数 字;对于 ave,既可以保存到某个列表中进行存储,也可以添加到一个累计总计 并跟踪调用次数。无论您如何执行计算,实际计算都需要在这里完成。getValue () 获取您的计算的最终值或当前值。所以,对于 SUM 操作,您将会返回总数/计 数操作。在正在运行的聚合器中,将只返回正在计算的值。

下一节的示例将展示如何创建一个简单的 Word Count 聚合器。此聚合获取一 列中的所有句子并计算字数,返回一个包含该列的字数的整数值。对这种聚合的 需求很少,所以还不存在这样的聚合。对于本文中的练习,建议使用 Eclipse BIRT All-in-One 分发版。

创建新聚合插件

要创建新聚合插件:

单击 File > New > Other 创建一个新插件项目。展开 Plug-In Development 文件夹,然后单 击 Plug-in Project。

在 New Plug-in Project 窗口中(如图 1 所示) ,在 ID 字段中为项目提供一个惟一名称,使用合适的信息完成 Version、Name 和 Provider 字段。

图 1. 项目属性

指定 Java™ 2 Platform, Standard Edition (J2SE) V1.5 作为执行环境,以保持与 BIRT 基本 兼容。

在 Options 区域,清除 This plug-in will make contributions to the UI 复选框。通过清除此复选框,可以限制可用模板的数量。我们不打算为此项目使 用模板。

在 Rich Client Application 区域,选择 No,因为这不是一个 Eclipse 富客户端项目。单击 Next。

在 Templates 页面上,清除 Create a plug-in using one of the templates 复选框,然后单击 Finish。如 果现在还未处于 Plug-In 开发透视图中,系统将提示您打开它。

设置扩展点

创建好新项目之后,就可以设置扩展点了。为此,执行以下操作:

在打开的清单窗口中,单击 Extensions 选项卡,然后单击 Add。

在 Extension Point Selection 窗口中(如图 2 所示),清除 Show only extension points from the required plug-ins 复选框。

图 2. 创建新扩展

在 Extension Point filter 字段中,键入 org.eclipse.birt.data。将会出 现聚合扩展点。当添加此扩展点时,系统将提示您添加依赖关系。

创建必要的聚合类

现在您已经添加了聚合扩展点,接下来需要添加一个新 AggregationFacTory 。为此,右键单击刚才添加的聚合扩展点,指向 New,然后单击 AggregationFacTory,如图 3 所示。注意,您并未添加聚合,聚合是以前的扩展 方法,这种方法现在已被淘汰。AggregationFacTory 是此插件的主要入口点,负 责注册可用的聚合类型,并在运行时创建这些聚合的实例。

图 3. 创建新 AggregationFacTory

添加了工厂的定义之后,您将获得一个文本项,其中包含工厂的完全限定包和 类名。从图 4 可以看到,该工厂名为 com.digiassn.blogspot.birt.aggregaTors.wordcount.WordCountFacTory。请记 住,此工厂可以注册和创建多个聚合类型,但这需要在代码体中操作。在 Extension Element Details 区域,键入或浏览到工厂类的名称,然后单击文本 框旁边的 class 超链接。

图 4. 创建新工厂类

New Java Class 向导已经拥有了合适的包和类信息。确认 Java Class 页面 上的设置(如图 5 所示),然后单击 Finish。

图 5. 工厂类属性

打开类的源代码,如图 6 所示。如果无法找到 org.eclipse.birt.* imports ,请返回并保存清单窗口中的更改。请记住,您需要为类添加必要的继承抽象方 法。

图 6. 工厂类框架

您的类包含 3 个函数:一个构造函数、一个 getAggregations() 方法(返回 一个 IAggrFunction),以及一个 getAggregations() 方法(返回一个列表)。 getAggregations() 方法向调用者返回一个 IAggrFunction 类型列表,使调用者 知道此工厂可以生成的各个聚合的类型。调用者负责在列表上进行迭代,并调用 IAggrFunctions 方法来获得描述。对于我们创建的工厂,我们不关心这些描述, 工厂将负责返回和维护此列表。

向 getAggregation() 方法传入聚合的名称。该方法获取一个名称并提供一个 IAggrFunction 结果,清单 1 显示了示例工厂。

清单 1. 完成之后的工厂类

public class WordCountFacTory implements  IAggregationFacTory {  HashMap aggregateMap;  public WordCountFacTory() {  aggregateMap = new HashMap ();  BasicWordcount wordCountAggregation = new BasicWordcount ();  aggregateMap.put(wordCountAggregation.getName(),  wordCountAggregation);  }  public IAggrFunction getAggregation(String aggregationName)  {  return aggregateMap.get(aggregationName);  }  public List getAggregations() {  return new ArrayList(aggregateMap.values ());  }}

创建单独的聚合描述类

接下来,在 src 文件夹中创建一个新包,将其命名为 com.digiassn.blogspot.birt.aggregaTors.implIn。在这个新包之下,创建一个 类 BasicWordCount。在 Java Class 窗口中,选择 Inherited abstract methods 复选框,以便此类可以继承 org.eclipse.birt.data.engine.api.aggregation.IAggrFunction 接口,如图 7 所示。

图 7. 创建新 IAggrFunction 实现

IAggrFunction 类具有两项任务:它将自身描述为工厂可以创建的聚合,它还 会创建 AccumulaTor 类的实例来为您的聚合执行实际工作。清单 2 给出了代码 。

清单 2. 完成后的聚合函数和 AccumulaTor 类

public class BasicWordcount implements IAggrFunction  {  private final static String sDescription =   "This aggregation will count all words in a column and  return the count.";  private final static String sName = "Word Count";  private final static String sDisplayName = "Basic Word  Count AggregaTor";  public int getDataType() {  return DataType.INTEGER_TYPE;  }  public Object getDefaultValue() {  return new Integer(0);  }  public String getDescription() {  return this.sDescription;  }  public String getDisplayName() {  return this.sDisplayName;  }  public String getName() {  return this.sName;  }  public int getNumberOfPasses() {  return 1;  }  public IParameterDefn[] getParameterDefn() {  IParameterDefn paramDef = new IParameterDefn() {   public boolean supportDataType(int paramType) {   if (paramType == DataType.STRING_TYPE)   {    return true;   }   return false;   }   public boolean isOptional() {   return false;   }   public boolean isDataField() {   return false;   }   public String getName() {   return "StringColumn";   }   public String getDisplayName() {   return "String Column";   }   public String getDescription() {   return "A column expression that is a String";   }  };  IParameterDefn[] parameterDefinitionArray = new  IParameterDefn[]     {paramDef};  return parameterDefinitionArray;  }  public int getType() {  return IAggrFunction.SUMMARY_AGGR;  }  public boolean isDataOrderSensitive() {  return false;  }  public AccumulaTor newAccumulaTor() {  return new AccumulaTor()  {   int sum;   @Override   public Object getValue() throws DataException {   return new Integer(sum);   }   @Override   public void onRow(Object[] incomingStrings) throws  DataException {   String localString = (String) incomingStrings [0];   sum += localString.split(" ").length;   }  };  }}

此类中的大部分方法只是简单描述要在 BIRT Aggregation Widgets 下拉列表 中显示的聚合的各个方面,比如数据类型、标题和描述信息。这 3 个方面有必要 进一步解释一下。首先是 getParameterDefn() 方法,它返回一个 IParameterDefn 对象数组,可以在该数组中定义聚合需要的参数。一个聚合可以 有多个参数,这就是为什么要以数组的形式返回参数。此方法向 BIRT 引擎简单 描述这些参数及其类型。在本例中,仅有一个参数(列表达式),它将是一个字 符串。

那么,如果参数在 getParameterDefn() 方法中进行描述,要将它们传入到何 处来执行实际工作呢?IAggrFunction 对象还充当着 AccumulaTor 类的工厂,该 对象应该在 newAccumulaTor 方法中创建。AccumulaTor 是在聚合中执行实际工 作的类。它有两个方法需要重载:getValue() 和 onRow()。对于在 BIRT 中处理 的每一行,如果使用此聚合,数据绑定将调用 onRow()。作为一个参数,onRow 接收一个包含聚合参数的数组,这些参数由 getParameterDefn() 描述。在更加 健壮的方案中,可以调用 getParameterDefn() 并测试传入 onRow() 的参数是否 与定义匹配。但是,本文中的简单示例跳过了这一步。onRow() 方法还负责执行 处理工作。在上面的聚合代码示例中,它仅用于增加正在计算的字符串总字数。 当报告准备好显示值时,它调用 getValue() 方法。

需要进一步说明的另一个元素是 IAggrFunctions getType() 方法。两种聚合 类型(SUMMARY_AGGR 和 RUNNING_AGGR)定义该方法属于哪种聚合类型;它出现 在报告表的表头或表尾,还是显示在每一行中;它在计算时显示的是累计总计, 还是平均值。

测试插件

可以轻松测试此插件,无需象测试任何 Eclipse 插件一样进行部署:只需启 动另一个 Eclipse 实例即可。启动另一个实例的最简单方式是从 plugin.xml/manifest 窗口的 Overview 选项卡上启动。在此选项卡上,在 Testing 区域,单击 Launch an Eclipse application 链接,如图 8 所示。

图 8. 测试插件

图 9 显示了一个简单报告,可以根据该报告来测试插件。将一个聚合组件插 入到此报告的表尾。

图 9. 向报告添加聚合

在 Aggregation Widgets 下拉列表中,选择 Basic Word Count 聚合器并输 入列表达式,以指向包含想要统计的句子的列,如图 10 所示。

图 10. Aggregation Builder

运行报告并验证结果。图 11 显示了生成的报告。

图 11. 报告结果

结束语

借助本文中的示例,您现在很好地了解了 BIRT 扩展点框架。现在您可以自行 构建一些聚合来在报告中使用,本文还展示了 BIRT 延伸到其开箱即用功能之外 的能力。请确保您使用了 plugin.xml/manifest 窗口的 Export Wizard 向导来 导出插件,并将该插件复制到您的 BIRT 目标环境(可以是 Web 应用程序或其他 BIRT 设计器环境)的 Plugins 文件夹内。否则,您部署的报告将无法运行,而 且编辑您报告的任何人都需要删除聚合定义。

一切伟大的行动和思想,都有一个微不足道的开始

使用EclipseBIRT扩展点:聚合

相关文章:

你感兴趣的文章:

标签云: