IBM Support

Using BIRT to create a report on the selected elements in the Project Explorer

Question & Answer


Question

How can you create a BIRT report that takes in input from the items selected in Project Explorer using IBM® Rational® Software Modeler (RSM) or IBM® Rational® Systems Developer (RSD) v7.0.5?

Cause

There is no out-of-the-box functionality to enable running a BIRT report taking in input the UML elements selected by the user in the Project Explorer.

However, you can create a custom XPath function that returns the nodeset of elements selected in the Project Explorer that can be used in your reports. The custom XPath function must be distributed as an Eclipse plug-in.

Answer

Disclaimer

All source code and/or binaries attached to this document are referred to here as "the Program". IBM is not providing program services of any kind for the Program. IBM is providing the Program on an "AS IS" basis without warranty of any kind. IBM WILL NOT BE LIABLE FOR ANY ACTUAL, DIRECT, SPECIAL, INCIDENTAL, OR INDIRECT DAMAGES OR FOR ANY ECONOMIC CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS), EVEN IF IBM, OR ITS RESELLER, HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.



The attached com.ibm.rational.example.report.xpath plug-in defines a custom XPath function called selectedElements which returns the nodeset of elements selected in the Project Explorer.
You can then use this function in the XPath Expression of the Table Mapping for a data set as in the attached image:




For example, if you wanted to create a data set that finds all selected items of type collaboration, you would use the following XPath expression:


instanceOf(selectedElements(),"uml:Collaboration")


where instanceOf is an XPath function described in the on-line help, and selectedElements() is the additional function defined by the plug-in attached to this technote.


PLUG-IN DESCRIPTION:

The plug-in.xml declares that this plug-in implements the extension point: org.eclipse.jet.xpathFunctionsas follows:

<?xml version="1.0" encoding="UTF-8" ?>
<?eclipse version="3.2"?>
<plugin>
  <extension point="org.eclipse.jet.xpathFunctions">
  <function
maxArgs="0"
minArgs="0"
implementation="com.ibm.rational.example.report.xpath.SelectedElements"
name="selectedElements" />
  </extension>
</plugin>



Note that the name attribute of the <function> tag in the extension point org.eclipse.jet.xpathFunctions will be the name of the function that you can call in your BIRT report, in this case selectedElements.
You can also see from the max-args and min-args attributes that this function takes no parameters.

The plug-in code contains the implementation class com.ibm.rational.example.report.xpath.SelectedElements that implements the interface:
org.eclipse.jet.xpath.XPathFunction
The result returned by the evaluate method is declared of type of type Object but it must contain a NodeSet org.eclipse.jet.xpath.NodeSet).
The getSelectedElements method of UMLUIHelper returns a java.util.List, which must be transformed to NodeSet. The helper class NodeSetUtil given below is required to transform this list into a NodeSet before returning it.

See the Related information section for more information on this topic.


/*
 *+------------------------------------------------------------------------
 *| Licensed Materials - Property of IBM                                  
 *| Copyright IBM Corp. 2008.  All Rights Reserved.                        
 *|                                                                        
 *| US Government Users Restricted Rights - Use, duplication or disclosure
 *| restricted by GSA ADP Schedule Contract with IBM Corp.                
 *+------------------------------------------------------------------------
 */
package com.ibm.rational.example.report.xpath;

import java.util.List;
import org.eclipse.jet.xpath.XPathFunction;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import com.ibm.xtools.modeler.ui.UMLModeler;

public class SelectedElements implements XPathFunction {

 public Object evaluate(List args) {

  final List[] result = new List[1];
  Display display = PlatformUI.getWorkbench().getDisplay();

  display.syncExec(new Runnable() {
   public void run() {
    result[0] = UMLModeler.getUMLUIHelper().getSelectedElements(
      "org.eclipse.ui.navigator.ProjectExplorer");
   }
  });  
  return NodeSetUtil.asNodeSet(result[0]);
 }
}



and the NodeSetUtil class:

package com.ibm.rational.example.report.xpath;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import org.eclipse.jet.xpath.NodeSet;

/**
 * Workaround copied from M2T Jet bugzilla
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=203970 
 * to adapt Java collection
 * or array of objects to a NodeSet.
 */
class NodeSetUtil {

 private static class NodeSetAdaptor implements NodeSet {
 
  private Collection collection;
 
  public NodeSetAdaptor(Collection collection) {
   this.collection = collection;
  }
 
  public boolean add(Object o) {
   return collection.add(o);
  }
 
  public boolean addAll(Collection c) {
   return collection.addAll(c);
  }
 
  public void clear() {
   collection.clear();
  }
 
  public boolean contains(Object o) {
   return collection.contains(o);
  }
 
  public boolean containsAll(Collection c) {
   return collection.containsAll(c);
  }
 
  public boolean equals(Object o) {
   return collection.equals(o);
  }
 
  public int hashCode() {
   return collection.hashCode();
  }
 
  public boolean isEmpty() {
   return collection.isEmpty();
  }
 
  public Iterator iterator() {
   return collection.iterator();
  }
 
  public boolean remove(Object o) {
   return collection.remove(o);
  }
 
  public boolean removeAll(Collection c) {
   return collection.removeAll(c);
  }
 
  public boolean retainAll(Collection c) {
   return collection.retainAll(c);
  }
 
  public int size() {
   return collection.size();
  }
 
  public Object[] toArray() {
   return collection.toArray();
  }
 
  public Object[] toArray(Object[] a) {
   return collection.toArray(a);
  }
 }
 
 private NodeSetUtil() {
  // do nothing, except prevent instantiation
 }

 /**
  * Wrap a Java {@link Collection} as a JET XPath {@link NodeSet}.
  * @param collection a non-null, but possibly empty collection
  * @return a node set
  * @throws NullPointerException
  */
 public static NodeSet asNodeSet(Collection collection) {
  if(collection == null) {
   throw new NullPointerException();
  }
  return new NodeSetAdaptor(collection);
 }

 /**
  * Wrap a Java array as a JET XPath {@link NodeSet}.
  * @param array a non-null, but possibly empty array.
  * @return a node set
  * @throws NullPointerException if <code>array</code> is <code>null</code>
  */
 public static NodeSet asNodeSet(Object[] array) {
  if(array == null) {
   throw new NullPointerException();
  }
  return new NodeSetAdaptor(Arrays.asList(array));
 }
}




INSTALLATION INSTRUCTIONS:
    1. Before you can install the plug-in into RSx 7.0.5 you must export it as a deployable plug-in.
    2. The resulting deployable plugin is attached as:
      com.ibm.rational.example.report.xpath_1.0.0.jar
    3. You can install this by copying it inside:
      C:\Program Files\IBM\Rational\SDP\plugins
    4. Then start RSx with the -clean command line switch once.
      For RSD: C:\Program Files\IBM\SDP\eclipse.exe" -product com.ibm.rational.rsd.product.ide -clean
      For RSM:
      C:\Program Files\IBM\SDP\eclipse.exe" -product com.ibm.rational.rsm.product.ide -clean
    5. To verify that the plug-in is installed, go to Windows->Show View->Other->Plug-in Registry
    6. Type: com.ibm.rational.example.report
      The plug-in should be found.


RUNNING A REPORT THAT USES THE PLUG-IN:

The Selected Collaboration Example Report project contains an example report design, a UML model and the report output when it was generated with two collaborations from the model selected in the Project Explorer.

Read the selectedCollaborationExample.pdf for more details about the XPath function and the example itself.

To run the report, follow these steps:
    1. Go to Windows -> Show View ->Other ->Reports Explorer
    2. Right click on the UML Report section and choose Add Existing Report
    3. Browse to the location of selectedCollaborationExampleReport.rptdesign
    4. Select ONE Collaboration in Project Explorer, right click on it and choose:
      Generate Report > Collaboration Report
    5. If you want to select multiple collaborations in Project Explorer, using the Ctrl or Shift keys, then the above context menu is not available. For that case, you must right click on the report in the Report Explorer and choose Generate Report


KNOWN LIMITATIONS:
It is not possible to use this approach if you intend to run the report by means of an Ant script.

com.ibm.rational.example.report.xpath_1.0.0.jarSelectedCollaborationExampleReport.zipcom.ibm.rational.example.report.xpath.source.zip

Related Information

[{"Product":{"code":"SSJP3D","label":"Rational Systems Developer"},"Business Unit":{"code":"BU053","label":"Cloud & Data Platform"},"Component":"Reports","Platform":[{"code":"PF016","label":"Linux"},{"code":"PF027","label":"Solaris"},{"code":"PF033","label":"Windows"}],"Version":"7.0.5","Edition":"","Line of Business":{"code":"LOB45","label":"Automation"}},{"Product":{"code":"SSCLKU","label":"Rational Software Modeler"},"Business Unit":{"code":"BU053","label":"Cloud & Data Platform"},"Component":"Reports","Platform":[{"code":"PF033","label":"Windows"},{"code":"PF016","label":"Linux"}],"Version":"7.0.5","Edition":"","Line of Business":{"code":"LOB45","label":"Automation"}}]

Document Information

Modified date:
16 June 2018

UID

swg21294342