Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents

Prerequisites

To author reports, you need to have:

  • Downloaded and installed the Jaspersoft Studio application

  • Obtained a basic familiarity with using this application.

  • Set up or arranged for read-only access to the CollectionSpace databases.

  1. Download and install the Jaspersoft Studio application. This is free, open source software from Jaspersoft, which you can download

...

  1. from https://community.jaspersoft.com/project/jaspersoft-studio/releases.

  2. Read the tutorials

...

  1. that you find useful

...

  1. : https://community.jaspersoft.com/wiki/jaspersoft-studio-tutorials-archive

  2. Ensure you have

...

  1. access to the database. If you are working on the server that hosts CollectionSpace, the default configuration will allow access. Otherwise, you need to have your admin allow remote access to the database by editing the PostgreSQL configuration files:

    1. In the main postgresql.conf file, there must be an entry like:

      Code Block
      listen_addresses = 'localhost, {your-machine}'        # what IP address(es) to listen on;

      where you or your administrator will replace "{your-machine}" with the IP address or hostname of the computer from which you will be connecting when you're authoring reports. See also the PostgreSQL documentation on Connections and Authentication.

    2. In PostgreSQL's host-based authentication file, pg_hba.conf, there must be an entry for a PostgreSQL database user account that will be given read-only privileges to the nuxeo database, for the purpose of performing queries and running reports. The following example specifies that access is granted to the nuxeo database to the PostgreSQL database user account named "reader," for remote connections from IP address 172.20.143.89, via username and password authentication (md5).

      Code Block
      host nuxeo reader 172.20.143.89/32 md5

      (In the example above, replace the example IP address given there with the actual IP address of the machine you will be connecting from. In place of specifying an individual IP address, you can instead specify a subnet range of addresses. For details, see the PostgreSQL documentation on the pg_hba.conf file..)

Writing a report

Steps Follow the instructions in the CollectionSpace User Manual to create a new report project in Jaspersoft Studio :

  1. Create a new datasource to access the data in your repository. The easiest way is to select Window->Welcome to iReport, and then use the Quick Start wizard to create a new database connection.
    1. Click the Step 1 - Create a new database connection link.
    2. Select Database JDBC connection
    3. Type in a name you choose to refer to this connection (E.g., "Our Museum on CollectionSpace")
    4. In the JDBC URL Wizard section, type in the name (or IP address) of the server that runs your database, and enter "nuxeo" in the Database field, and then click on the Wizard button to generate the JDBC URL.
    5. Enter "reader" for the Username, and your local password.
    6. Click on the Test button to ensure your entries are correct.
  2. Create a new report. The easiest way is to use the Quick Start wizard on the Welcome window:
    1. Click the Step 2 - Create a new report link.
    2. Select a template you like, and click the Launch Report Wizard button.
    3. Set a name and location, and click Next.
    4. Choose the datasource your defined in Step 4 above.
    5. Click Design Query, select a table (e.g., collectionobjects_common), choose fields, and complete the wizard according to the tutorials.

You can explore the report authoring tool from this basic report. You will likely want to rename the labels, as the default labels based upon the data-model are not very user-friendly. In addition, certain fields will benefit from some expressions to simplify the value.  For example, field values that refer to authority terms (Person, Org, etc.) can be easily converted to a display value using the following expression, replacing "field" with the field name you are accessing:

Code Block
($F{field}==null || $F{field}.isEmpty())?
  "":$F{field}.substring(
     $F{field}.lastIndexOf( ")" )+2,
       $F{field}.length()-1).replaceAll("[+]"," ")

In addition, you will want to add two additional clauses to the query, to filter your results to the appropriate tenant, and to filter documents that have been soft-deleted (marked as deleted, but still present in the database). Here is an example query that gets values from the acquisition schema:

Code Block
SELECT
acquisitions_common."originalobjectpurchasepricevalue" AS acquisitions_common_originalobjectpurchasepricevalue,
acquisitions_common."transferoftitlenumber" AS acquisitions_common_transferoftitlenumber,
acquisitions_common."acquisitionreferencenumber" AS acquisitions_common_acquisitionreferencenumber,
acquisitions_common."acquisitionmethod" AS acquisitions_common_acquisitionmethod,
acquisitions_common."acquisitionauthorizerdate" AS acquisitions_common_acquisitionauthorizerdate,
acquisitions_common."acquisitionauthorizer" AS acquisitions_common_acquisitionauthorizer,
acquisitions_common."acquisitionreason" AS acquisitions_common_acquisitionreason
FROM
"public"."acquisitions_common" acquisitions_common
INNER JOIN "public"."hierarchy" hierarchy ON acquisitions_common."id" = hierarchy."id"
INNER JOIN "public"."collectionspace_core" core ON acquisitions_common."id" = core."id"
INNER JOIN "public"."misc" misc ON misc."id" = hierarchy."id"
WHERE core.tenantid = $P{tenantid} AND misc.lifecyclestate != 'deleted'
$P!{where_clause}

In the query above, the tenant ID has been specified as a property (tenantid) in Jaspersoft Studio, and the property value is used in the query. CollectionSpace will pass in the current tenant ID when the report is run on the CollectionSpace server, so the same report can be used for different tenants in the system. For your testing, set the tenantid property to have a default value corresponding to the tenant you most commonly use. This id is the one specified in the tenant configuration file for the services, for your tenant. See also: Creating your new tenant.

You will also note an additional where_clause parameter. This is used to pass in specific id values, when the report is to be run on a particular record. In the reports provided with CollectionSpace, this parameter often has a default value similar to:

Code Block
(($P{csid} == null || ($P{csid}.length() == 0)) ? "" : " AND hierarchy.name = '" + $P{csid} + "'")

The effect of this definition is to look for a csid parameter passed in from CollectionSpace, and produce a report on that single record if it is set. If the value is not set by CollectionSpace (when the report is run without any context), the report is run on all records (of a certain type). Authoring a report this way allows it to be run either for a single record, or without a context (from the Tools/Reports screen).

There are currently several reports installed with CollectionSpace. You can see these reports (and download them to view in Jaspersoft Studio) in the CollectionSpace source code repository.

Preparing reports for running from within CollectionSpace

To make the report available to CollectionSpace:

  1. Copy the .jrxml file to the reports directory on the server. Report files should be installed in the cspace/reports directory under the Tomcat directory (whose path should be in the CSPACE_JEESERVER_HOME environment variable). Note the name of the file, e.g., "acq_basic.jrxml".
  1. Create a report record to register the report with CollectionSpace. This requires you to run a curl command to send the record to the server's REST API. The following example declares that the report "acq_basic.jrxml" should be shown to users when they are editing Acquisition records. Set the outputMIME value to the desired default output type for the report. This can be any output type supported by JasperReports.
Code Block
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<document name="report">
  <ns2:reports_common xmlns:ns2="http://collectionspace.org/services/report">
    <name>Sample Acquisition Report</name>
    <notes>This is a sample Acquisition report.</notes>
    <forDocTypes>
      <forDocType>Acquisition</forDocType>
    </forDocTypes>
    <supportsSingleDoc>true</supportsSingleDoc>
    <supportsDocList>false</supportsDocList>
    <supportsGroup>false</supportsGroup>
    <supportsNoContext>true</supportsNoContext>
    <filename>acq_basic.jrxml</filename>
    <outputMIME>application/pdf</outputMIME>
  </ns2:reports_common>
</document>

Your admin can use the following command to create the report record in CollectionSpace. Replace "{yourtenant}" with the name of your tenant, and replace "{password}" with your admin password. This assumes you have saved the XML file above as "report.xml":

Code Block
curl -X POST http://localhost:8180/cspace-services/reports
  -i -u admin@{yourtenant}.collectionspace.org:{password}
  -H "Content-Type: application/xml" -T report.xml

Documents and forDocType values

It's common to create reports that describe Object records that are related to a procedural record, such as an Intake. In this case, the context document is the procedural record (the Intake, Accession, etc.), even though the report will actually generate output about the related Object records. The forDocType values present in the XML above control where the user will see the report in the UI. You may infer from the XML above that one report can appear for multiple types of records -- this is useful when a report summarizes Objects associated with multiple kinds of procedural records (Intakes, Acquisitions, Loans, etc.). The value of the csid parameter passed to the report from CollectionSpace will be the unique id of the record on which the user ran the report (e.g., the Intake, or the Acquisition). Your report query must select Object records associated to that record through relationsand establish a connection to CollectionSpace: Creating and Running a CollectionSpace Report in Jaspersoft Studio.

A report retrieves data using SQL. Here is an example SQL query that gets field values from Acquisition records:

Code Block
SELECT
acquisitions_common."originalobjectpurchasepricevalue" AS acquisitions_common_originalobjectpurchasepricevalue,
acquisitions_common."transferoftitlenumber" AS acquisitions_common_transferoftitlenumber,
acquisitions_common."acquisitionreferencenumber" AS acquisitions_common_acquisitionreferencenumber,
acquisitions_common."acquisitionmethod" AS acquisitions_common_acquisitionmethod,
acquisitions_common."acquisitionauthorizerdate" AS acquisitions_common_acquisitionauthorizerdate,
acquisitions_common."acquisitionauthorizer" AS acquisitions_common_acquisitionauthorizer,
acquisitions_common."acquisitionreason" AS acquisitions_common_acquisitionreason
FROM
"public"."acquisitions_common" acquisitions_common
INNER JOIN "public"."hierarchy" hierarchy ON acquisitions_common."id" = hierarchy."id"
INNER JOIN "public"."collectionspace_core" core ON acquisitions_common."id" = core."id"
INNER JOIN "public"."misc" misc ON misc."id" = hierarchy."id"
WHERE core.tenantid = $P{tenantid} AND misc.lifecyclestate != 'deleted'
$P!{where_clause}

The above query contains clauses to constrain the results to the appropriate tenant, and to filter out documents that have been soft-deleted (marked as deleted, but still present in the database). The tenant ID has been specified as a property (tenantid) in the report, and the property value is used in the query. CollectionSpace will pass in the current tenant ID when the report is run on the CollectionSpace server, so the same report can be used for different tenants in the system. For your testing, set the tenantid property to have a default value corresponding to the tenant you most commonly use. This id is the one specified in the tenant configuration file for the services, for your tenant. See also: Creating your new tenant.

You will also note an additional where_clause parameter. This is used to pass in specific id values, when the report is to be run on a particular record. In the reports provided with CollectionSpace, this parameter often has a default value similar to:

Code Block
(($P{csid} == null || ($P{csid}.length() == 0)) ? "" : " AND hierarchy.name = '" + $P{csid} + "'")

The effect of this definition is to look for a csid parameter passed in from CollectionSpace, and produce a report on that single record if it is set. If the value is not set by CollectionSpace (when the report is run without any context), the report is run on all records (of a certain type). Authoring a report this way allows it to be run either for a single record (from the record editor screen), or without a context (from the Tools/Reports screen).

There are currently several reports installed with CollectionSpace. You can see these reports (and download them to view in Jaspersoft Studio) in the CollectionSpace source code repository.

Field Template Expressions

When formatting fields, Jaspersoft allows for expressions to be used when formatting your fields. Reports will default to Java expressions and other languages can be used by by setting language attribute in the header of the report jrxml, e.g.

Code Block
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" 
name="notice_inventory_completion" language="javascript" whenNoDataType="NoDataSection" ...>
Note

Setting the language will make ALL expressions used in the report interpreted by the chosen language. In the above example any Java expressions that were previously written for parameters would need to be updated to be compatible with JavaScript.

Groovy and JavaScript are provided as part of the default CollectionSpace installation with the following versions:

Language

Version

Supported Functions

Groovy

2.4.14

JavaScript (Rhino)

1.7.12

https://mozilla.github.io/rhino/compat/engines.html

Report description XML record

For each report created, best practice is to create an XML record that has the same name as the report .jrxml file, and which lives in the same place. For instance, if you create acq_basic.jrxml, also create acq_basic.xml.

The XML record is used to add the report to CollectionSpace, and sets report properties and behaviors. An example report XML file is shown below.

The rest of this section details the meaning/use of the XML record elements.

Code Block
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<document name="report">
  <ns2:reports_common xmlns:ns2="http://collectionspace.org/services/report">
    <name>Sample Acquisition Report</name>
    <notes>Reports on objects related to a given Acquisition record</notes>
    <forDocTypes>
      <forDocType>Acquisition</forDocType>
    </forDocTypes>
    <supportsSingleDoc>true</supportsSingleDoc>
    <supportsDocList>false</supportsDocList>
    <supportsGroup>false</supportsGroup>
    <supportsNoContext>true</supportsNoContext>
    <filename>acq_basic.jrxml</filename>
    <outputMIME>application/pdf</outputMIME>
  </ns2:reports_common>
</document>

name element

The name of the report as displayed in CollectionSpace UI

notes element

Description of report shown for report in CollectionSpace UI

forDocTypes / forDocType element grouping

Controls the record type(s) in which the user will see the report in the UI. This may or may not match the record type(s) contained in the resulting report.

The above report will be available from inside an Acquisition record. The unique system id of the record from which the report is invoked will be passed to the report in the csid parameter. The report returns information about Objects because the report query selects Objects related to the given Acquisition.

The forDocType element is repeatable, so the above report could easily be generalized to a “Related Objects” report runnable from any procedure record type listed in forDocTypes.

Where to find the correct docType values

Registered docType values will be categorized into service groups, available via the /servicegroups REST-ful API service for the given CollectionSpace instance.

Examples for the Anthro sandbox site:

The docType value for Objects is CollectionObject (Check /servicegroups/object for your instance to verify.)

supportsSingleDoc element

If true, the report will be available to run from inside any record type listed in forDocTypes. The above report will be available from inside an Acquisition record. The unique system id of the record from which the report is invoked will be passed to the report in the csid parameter.

If false, the report will not be available when viewing an individual record.

supportsDocList element

If true, the report will be available on single-record-type lists of the record types specified in forDocTypes. The user must select one or more records in the list in order to run the report.

If false, the report is not available in such record lists.

The unique ids of the selected records are passed to the report in the csidlist parameter.

Code Block
languagexml
<forDocTypes>
  <forDocType>CollectionObject</forDocType>
</forDocTypes>
<supportsSingleDoc>false</supportsSingleDoc>
<supportsDocList>true</supportsDocList>

The above would cause the report to be available from:

  1. Search results where the search was limited to Objects

  2. The “Objects related to {record number}” page available from any procedure record

This report would not be available from the following because these are lists of mixed record types:

  1. A search scoped to “All Records”

  2. The “Uses of {term}” page available for authority terms

Warning

The csidlist param is currently passed to the report in an HTTP header. Due to limitations on how long such headers may be, if too many records are selected, users will hit:

Jira Legacy
serverSystem Jira
serverId4f23a7bf-fe0d-390f-9b92-bdff15338913
keyDRYD-1428

The supportsGroup element can be used to provide a workaround for this. See that section for details.

supportsNoContext element

If true, the report is runnable from Tools > Reports without requiring the user to select any records. The report runs across the entire database. No csid, csidlist, or groupcsid parameter values are passed to the report. The report’s whereclause should handle selecting all records meeting the desired criteria.

If false, the report cannot be run on the entire database.

Note that, if supportsNoContext is true and the other supports elements are false, the forDocTypes values are irrelevant. You could specify forDocType = Uoc, but if the whereclause parameter in the report is written to select object data, the report is returning object data! It won’t be shown in any records or on any record lists.

TODO: Test whether forDocTypes can be omitted for such reports

supportsGroup element

Only one of the 41 reports that ship with CollectionSpace right now have this one set to true. Here is the relevant part of its .xml:

Code Block
languagexml
<forDocTypes>
  <forDocType>CollectionObject</forDocType>
</forDocTypes>
<supportsSingleDoc>true</supportsSingleDoc>
<supportsDocList>true</supportsDocList>
<supportsGroup>true</supportsGroup>
<supportsNoContext>false</supportsNoContext>

This means you can run the report from:

  • within a given Object record

  • a list of Object records

  • within a Group record

Running the report from a Group record passes the csid of the Group to the report as the groupcsid parameter.

Note that a Group may “contain” (i.e. be related to) Objects, other Groups, or any other procedural record types. Different types of records can be in a group together.

The reporting logic does not check whether a Group contains the target record type(s) when determining whether to display the report as runnable on the Group. If you have a group that consists of Loan In and Loan Out procedures, the above report will be runnable from the Group. The resulting report contain no records.

For reports with supportsGroup = true, the whereclause in the report must appropriately select records of the desired types from all the records related to the Group. In the above report, the whereclause is complex, providing selection logic for (1) a single Object; (2) a list of Objects; and (3) all the Objects related to a given group.

With supportsGroup = false, this report could still be run on all the Group’s Related Objects, with some extra clicking. However, if there are over ~200 related Objects, users might receive an error due to the issue linked in the supportsDocList section.

Until that issue has been resolved, you might consider implementing supportsGroup = true as a workaround. If a user needed to generate a report on 500 Objects, they could create a temporary Group, relate the 500 Objects to the Group, and then run the report on the Group. Since only the Group’s csid is sent to the report as a parameter,

Jira Legacy
serverSystem Jira
serverId4f23a7bf-fe0d-390f-9b92-bdff15338913
keyDRYD-1428
is not triggered.

filename element

The .jrxml filename. Ideally the XML file containing the report description should be exactly the same, but with “.xml” instead of “.jrxml” file extension.

outputMIME element

When this element appears as a child of the ns2:reports_common element, it sets the default output format for the report. The default output format is preselected when a user invokes the report. All supported report formats are available for selection.

Note that you can also do this:

Code Block
<ns2:reports_common xmlns:ns2="http://collectionspace.org/services/report">
 [...]
  <supportsOutputMIMEList>
    <outputMIME>text/csv</outputMIME>
  </supportsOutputMIMEList>
  <outputMIME>text/csv</outputMIME>
</ns2:reports_common>

supportsOutputMIMEList allows you to constrain the output formats available to selection to the ones you specify. Multiple outputMime elements can be nested inside this element.

The top-level, non-nested outputMIME element sets CSV as the default output format.

The list of currently-supported report output MIME types can be found in the default reportMimeTypes option list configuration.

The above config looks redundant: why specify a preferred output format when there is only one output format? Indeed, the report can be run without specifying the default output format. However, the non-nested/top-level outputMIME value is used to populate the Default output format in the Tools > Reports screen, so it is best to provide this information.

...

Preparing reports for running from within CollectionSpace

To make the report available to CollectionSpace:

  1. Copy the .jrxml file to the reports directory on the server. Report files should be installed in the cspace/reports directory under the Tomcat directory (whose path should be in the CSPACE_JEESERVER_HOME environment variable). Note the name of the file, e.g., "acq_basic.jrxml".

  2. CollectionSpace admins and any other users with Utility Resources > Reports > Write permission can use the following command to create the report record in CollectionSpace:

    1. Replace http://localhost:8180 with the base url of your CollectionSpace instance.

    2. Replace {username} with your CollectionSpace user name and {password} with your password.

    3. This assumes you have saved the XML file discussed above as "acq_basic.xml" and are running the command from the directory containing the file.

Code Block
curl -X POST http://localhost:8180/cspace-services/reports
  -i -u {username}:{password}
  -H "Content-Type: application/xml" -T acq_basic.xml

Installing reports automatically

As of release 7.2, CollectionSpace automatically installs built-in reports on startup, so creating report records manually using curl is not necessary. To make a report automatically install:

  1. Add the .jrxml file to the built-in reports directory in the services source tree on your server. This directory is located at services/report/3rdparty/jasper-cs-report/src/main/resources inside the services source code directory.

  2. Add a report metadata record .xml file to the same directory. This file must have the same name as the report file, but the extension .xml instead of .jrxml.

  3. Add the report to the tenant bindings file for your tenant. This file is located at services/common/src/main/cspace/config/services/tenants/{yourtenant}/{yourtenant}-tenant-bindings.delta.xml inside the services source code directory. Replace "{yourtenant}" with the name of your tenant. The tenant binding file for the publicart tenant contains an example of what to add: https://github.com/collectionspace/services/blob/676faa9cf37ee4d99816d3392eb1984d247cfb0b/services/common/src/main/cspace/config/services/tenants/publicart/publicart-tenant-bindings.delta.xml#L11-L22. For each report you want to have installed automatically, create property with the key "report", and set the value to the name of the report (the name of the .jrxml and .xml files, without the extension).

  4. Redeploy the services, and restart CollectionSpace. The report should appear in the CollectionSpace UI.

Running a report

You can run (invoke, or generate) a report:

  • Via the CollectionSpace user interface:

    • By clicking on a report from the "Reports" list in the sidebar of record editor screens. This list will display reports, if any, that you can run in the current context.

    • By selecting search results, and clicking on a report from the "Reports" list in the sidebar of search result screens. This list will display reports, if any, that you can run in the current context.

    • By selecting a report on the Tools/Reports screen, and clicking the "Run..." button. This allows you to select the context in which to run the report.

  • Programmatically, via the Reporting Service REST APIs.

Deleting a report

To delete a report, use the Services Layer REST API to:

  • Make a call to that API to list Report records.

  • From that list, find the CSID of the relevant Report record.

  • Make a second call to that API to delete that record, via its CSID.

The CRUD+L (Create, Read, Update, Delete, List) section of the Reporting Service RESTful APIs describes how to make these calls.

...