【原创】Cognos 8 SDK 使用实例

至此,我们已经可以通过 Query Studio 和 Report Studio 直接使用 package 中相应数据创建报表和查询了,但本文意在说明 SDK 的使用,下面我们就使用 SDK 开发一个基于 Web 生成 Cognos 报表的应用,来展示如何利用 Cognos SDK 生成一个简单的二维报表及其对应的柱状图。用户可...显示全部
至此,我们已经可以通过 Query Studio 和 Report Studio 直接使用 package 中相应数据创建报表和查询了,但本文意在说明 SDK 的使用,下面我们就使用 SDK 开发一个基于 Web 生成 Cognos 报表的应用,来展示如何利用 Cognos SDK 生成一个简单的二维报表及其对应的柱状图。用户可以从模型中选择报表中的行和列(Dimension),以及度量(Measure)。

获取服务

首先根据需要创建 Web 应用项目,并将应用需要依赖的 library 引入项目,将cognos_homec8sdkjavalib目录下的 jar 文件复制到 Web 项目的 lib 目录下,这样我们就可以在 Web 应用中使用 Cognos 8 SDK 了。首先要建立与 Cognos 所需服务的连接,在 Cognos SDK 里,不同的功能是由不同的服务提供的,例如提供管理内容和认证服务的 Content Manager service,管理报表服务的 Report service。每一个服务都是通过相应的一组 java 接口调用 BI Bus API 实现的。其中最主要的接口类是 [service]_Service 和 [service]_Port。[service]_ServiceLocator 是 [service]_Serviced 的实现类,通过 [service]_ServiceLocator 可获得具体服务的 [service]_Port,通过 [service]_Port 我们就可以而调用服务所提供的相应功能了。

如下代码展示了如何获得 report service port:
清单 1. 获取 report service port

// 实例化所需服务的 ServiceLocator
ReportService_ServiceLocator reportLocator = new ReportService_ServiceLocator();
// 通过 ServiceLocator 获得 ServicePort
ReportService_Port reportService =
  reportLocator.getreportService("http://localhost:9300/p2pd/servlet/dispatch");


获取模型列表

接下来我们就要获得所有已经发布的模型,展示在页面上供用户选择,如下图所示:

1.png



我们需要使用 Content Manager service 的查询功能,其查询功能主要由query(SearchPathMultipleObject searchPath, PropEnum[] properties, Sort[] sortBy, QueryOptions options)方法实现,其中:

    * SearchPathMultipleObject参数指明要查找对象的路径,搜索路径在 Cognos 8 SDK 中的使用是非常广泛而且重要的,它遵循 XPath 的语法,如要搜索公共目录的根路径为/content/,这里我们要查找公共目录中的所有 package 对象,而不考虑 package 的具体位置,将搜索路径就设成/content//package。若需要访问特定用户的目录,则需要通过用户的 Account 对象,获取其搜索路径,如:[account].getSearchPath().getValue()+”folder[@name=”My Folders”]”。
    * PropEnum指明要查找对象具体哪些属性。
    * Sort是指明返回对象的排序规则,可以设定是按照哪个 PropEnum 属性排序,通过其中的 OrderEnum 指明是正序还是倒序。
    * QueryOptions指明本次查询的参数,例如是同步查询还是异步查询。

例子中我们搜索公共目录下所有 package 对象,返回相应的 defaultName 和 searchPath,即模型名称和是模型具体的查询路径。采用默认排序和默认查询属性。我们将查询到的所有模型对象放入一个 HashMap 对象,从而在 web 页面展示给用户。代码如下:

清单 2. 获取模型

//Get ContentManagerService
ContentManagerService_Port cms = getContentManagerService();
//Query model objects
BaseClass baseClassArray[]
         = cms.query(new SearchPathMultipleObject("/content//package"),
  new PropEnum[]{
  PropEnum.defaultName,
  PropEnum.searchPath},
  new Sort[]{},
  new QueryOptions());
  
//Put model name and path in to a hashmap
HashMap models = new HashMap();
for (BaseClass baseClass : baseClassArray) {
  if(baseClass.getClass().getName()
  .equals("com.cognos.developer.schemas.bibus._3._package")){
  models.put(baseClass.getDefaultName().getValue(),
baseClass.getSearchPath().getValue());
  }
}

获取模型的元数据

当用户选择了一个具体模型,我们要获得其选中模型的元数据,并显示成列表供用户选择,组成报表的行,列和度量。如下图所示:


模型元数据的获取需要通过 report service。首先我们要组织查询元数据的 xml 格式的字符串。元数据查询 xml 字符串是以 metadataRequest 作为 root 结点,此结点有 connection 属性,其值就是我们通过上一步骤获得的 searchPath。此外我们就要通过一个或多个 结点指明要查询模型的属性。在本例中我们要查询模型 folder,querySubject 以及 queryItem 结点的 name,datatype,_path,_ref 和 usage 属性。

    * queryItem结点是 folder 结点和 querySubject 结点的子节点,其中所包含就是模型文件中的具体数据项。
    * name属性是数据项的名字,用来显示在 web 界面。
    * dataType属性指明此数据项的数据类型。例如是字符或者数字等。
    * _Path属性指明此数据项的查询路径。
    * _ref属性指明此数据项在模型中的路径。
    * usage属性指明此数据项的使用类型,例如度量或维度等。

查询字符串如下:
清单 3. 模型元数据查询字符串

String modelPath =
"/content/folder[@name='Samples']/folder[@name='Models']/package[@name='CognosSample']"
String sXML = ""
  + ""
  + ""
  + ""
  + ""
  + ""
  + ""
  + ""
  + ""
  + ""
+ ""
  + "
"
  + "
"
  + "
";


组织好 metadataRequest 查询字符串后,我们就要通过调用 report service 的runSpecification(AsynchSpecification specification, ParameterValue[] parameterValues, Option[] options)方法获得所需模型的元数据。

    * AsynchSpecification就是我们所生成的 metadataRequest 查询字符串。
    * ParameterValue当我们要生成具体的报表,而且此报表需要参数时,通过 ParameterValue 指明参数。
    * Option指明运行的参数,例如是同步还是异步。

清单 4. 获取模型元数据代码

// 通过上面生成的 metadataRequest 查询字符串创建 ReportServiceMetadataSpecification 对象。
ReportServiceMetadataSpecification metadataSpec =
new ReportServiceMetadataSpecification();
metadataSpec.setValue(new Specification(sXML));
// 运行 report service 的 runSpecification 方法
AsynchReply runResponse = conn.getReportService()
  .runSpecification(metadataSpec, new ParameterValue[]{}, new Option[]{});
  
// 获取模型的元数据
AsynchDetailReportMetadata reportMetadata;
boolean foundMetadata = false;
String sMetaData = "";
for(int i=0; i  if (runResponse.getDetails()[i] instanceof AsynchDetailReportMetadata) {
  foundMetadata = true;
  reportMetadata = (AsynchDetailReportMetadata) runResponse.getDetails()[i];
  sMetaData = reportMetadata.getMetadata().toString();
  }
}收起
参与42

查看其它 41 个回答eagleVShorse的回答

eagleVShorseeagleVShorse软件开发工程师汉端科技
这个貌似以前看过。。。
互联网服务 · 2011-03-12
浏览572

回答者

eagleVShorse
软件开发工程师汉端科技

eagleVShorse 最近回答过的问题

回答状态

  • 发布时间:2011-03-12
  • 关注会员:0 人
  • 回答浏览:572
  • X社区推广