Writing custom XPath functions

Before you can add certain kinds of model information to a report (RPTDESIGN file), you must write a custom XPath function to extract the information from the target models.
Prerequisite: To complete this task, you must be familiar with plug-in development in the Eclipse Plug-in Development Environment and with the UML2 API.
To write a custom XPath function:
  1. Create a new plug-in project:
    1. In the Plug-in Development perspective, click File > New > Other, expand Plug-in Development, select Plug-in Project, and click Next.
    2. Type a plug-in ID such as com.ibm.field.birt.xpath_extensions; then click Next and Finish. The plug-in is added to the Package Explorer view, and information about the plug-in is displayed in the Plug-in Manifest Editor view on the Overview page.
  2. Extend the org.eclipse.jet.xpathFunctions extension point.
    1. On the Overview page, click the Extensions tab; then click Add.
    2. Clear the Show only extension points from required plug-ins check box.
    3. In the Extension Point filter field, type *.jet, and in the list of extensions double-click org.eclipse.jet.xpathFunctions.
    4. To confirm that you want to add the plug-in to the list of plug-in dependencies. click Yes.
    5. Click the MANIFEST.MF tab, and add org.eclipse.uml2.uml to the Require_Bundle list so that the plug-in has visibility to the UML API. The code for the list should look like this:
      Require_Bundle: org.eclipse.ui,
        org.eclipse.core.runtime,
        org.eclipse.uml2.uml,
        org.eclipse.jet
    6. Click the plugin.xml tab and modify the <function> definition to define the custom function. For example, if you are defining a function that is named SlotValue, has two arguments, and is implemented in the class com.ibm.field.birt.xpath_extensions.SlotValue, the code would look like this:
      <function
           implementation="com.ibm.field.birt.xpath_extensions.SlotValues"
           maxArgs="2"
           minArgs="2"
           name="slotValue">
      </function>
    7. Click File > Save.
  3. Create a code shell and link it to the plug-in:
    1. In the Package Explorer view, right-click the new plug-in project; then click New > Class.
    2. In the Package field, specify the name of the plug-in project.
    3. In the Name field, type a name for the class. Use the same name as you assigned to the new function. For example, for the function defined in step 2, the name would be SlotValue.
    4. To add an interface, click Add.
    5. In the New Java Class dialog box, in the Choose interfaces field, type XPathFunction; then from the list of matching items, select XPathFunction - org.eclipse.jet.xpath, click OK, and click Finish.
  4. Add code to the Java™ file for the XPath function to make it accomplish the task that you want, and save the file.

    For example, if you want the function SlotValue to iterate through the nodes that result from the first argument (an XPath expression), and when it finds an instance specification, to return the value of the slot that the slotname argument specifies by invoking the getStringValue function, you would write the following code:

    package com.ibm.field.birt.xpath_extensions;
    
    import java.util.Iterator;
    import java.util.List;
    
    import org.eclipse.jet.xpath.NodeSet;
    import org.eclipse.jet.xpath.XPathFunction;
    import org.eclipse.uml2.uml.InstanceSpecification;
    import org.eclipse.uml2.uml.Slot;
    import org.eclipse.uml2.uml.ValueSpecification;
    
    public class SlotValue implements XPathFunction {
    	
    	public String getStringValue(InstanceSpecification ia, String slotname) {
    		List slots = ia.getSlots();
    		for (Iterator iterator = slots.iterator(); iterator.hasNext();) {
    			Slot slot = (Slot) iterator.next();
    			String definingFeatureName = slot.getDefiningFeature().getName();			
    			if (definingFeatureName.equals(slotname)) {
    				List values = slot.getValues();
    				for (Iterator iterator2 = values.iterator(); iterator2
    						.hasNext();) {
    					ValueSpecification value = (ValueSpecification) iterator2.next();
    					return value.stringValue();
    				}
    			}
    		}
    		return null;
    	}
    	
    	public Object evaluate(List args) {
    		Object obj = args.get(0);
    		String slotname = (String) args.get(1);
    		if (obj instanceof NodeSet) {
    			NodeSet ns = (NodeSet) obj;
    			for (Iterator iterator = ns.iterator(); iterator.hasNext();) {
    				Object item = (Object) iterator.next();
    				if (item instanceof InstanceSpecification){
    					InstanceSpecification ispec = (InstanceSpecification) item;
    					if ((slotname != null)&&(slotname.length()>0))
    						return getStringValue(ispec,slotname);
    				}
    			}
    		}
    		return null;
    	}
    }
  5. Create a new feature plug-in project:
    1. Click File > New > Other, expand Plug-in Development, select Feature Project, and click Next.
    2. In the Project name field, type a project name and click Next. It is often useful to assign a feature name that is similar to the name of the plug-in; for the plug-in com.ibm.field.birt.xpath_extensions, you might choose com.ibm.field.birt.xpath_extensions.feature.
    3. To bundle the plug-in with the feature, select the check box for the plug-in that you created in step 1 and click Finish. The feature is added to the Package Explorer view, and information about the feature is displayed in the Feature Manifest Editor view on the Overview page.
    4. On the Overview page, in the Name field, type a feature name such as XPath Extensions Feature.
    5. On the Overview page, click the link for Export Wizard.
    6. Select Archive file, specify a location and a name for the file, such as xpath_extensions.zip, and click Finish.
    Note: You can use this feature plug-in for multiple custom XPath function projects.
  6. Import the new plug-in into the instance of Eclipse where you are designing reports:
    1. Extract the archive file to a directory such as C:/temp/xpath_extensions.
    2. In Eclipse, click Help > Software Updates > Find and Install.
    3. In the Install/Update wizard, click Search for new features to install and click Next.
    4. Click New Local Site, select the folder that contains the feature and plug-in, click OK, and click Finish.
    5. In the Search Results dialog box, select your feature and click Next.
    6. If you agree to the terms of the license agreement, select I accept the terms in the license agreement, click Next, and click Finish.
    7. When you receive a prompt to restart your computer, click Yes.
You can now use the new XPath extension in report designs.
Note: Users of report designs must also import the new feature before they can generate reports from report designs that depend on the custom XPath functions. The topic "Importing custom XPath functions" provides general information, but you might want to provide custom user documentation to accompany the RPTDESIGN file that explains where users can obtain the feature and how they can use it.
Related tasks
Importing custom XPath functions
Related reference
Tips for designing model reports

Feedback