This is the documentation of the JavaTM implementation of Sxml.


Copyright © 2000-2001 University of Colorado.
Author: Antonio Carzaniga.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

Please, send comments, suggestions, complaints about this documentation to Antonio Carzaniga <carzanig@cs.colorado.edu>.


Sxml Basics

Sxml automates the use of XML documents as sources of event notifications with the Siena publish/subscribe service.

Sxml Architecture

Sxml creates Siena notifications by mapping elements and attributes of an XML document into attributes of a Siena notification. The mapping is defined through an {@link siena.sxml.EventMap} object. Sxml can also attach the XML source data to the Siena notification it produces, so that subscribers can later extract the XML source from notifications.

Sxml uses XPath expressions to select data of interest from the XML document. Since an XPath expression may select multiple nodes (elements and attributes) of an XML document, an Sxml mapping also defines the encoding method for multiple selections. This is an example of a Sxml mapping:

Siena attributeXPathMultivalue specification
stringname/person/@namefirst
intage/person/@agefirst
stringfather/person/links[relation=father]/person/@namefirst
stringmother/person/links[relation=mother]/person/@namefirst
floatsalary/person/job/@salarylast
stringjobs/person/job/@companyseparator ", "
stringeducation/person/educationxml

An XPath expression may select more than one element within an XML document, therefore Sxml allows to specify a method for synthesizing a Siena attribute value from multiple XML nodes.

Examples

Simple publisher of XML data

XMLPublisher.java:

import siena.*;
import siena.sxml.*;
//
// a simple publisher of XML data
//
public class XMLPublisher {
    public static void main(String args[]) {
	if (args.length < 2) {
	    System.err.println("Usage: XMLPublisher   [event..]");
	    System.exit(1);
	}
	try {
	    Siena siena = new ThinClient(args[0]);
	    EventMap m = new EventMap();
	    //
	    // reads the set of mapping rules from a file
	    //
	    m.importRules(args[1]);
	    //
	    // configure the Sxml map to attach the XML sources to
	    // the notifications that it it produces
	    //
	    m.attachXml();
	    if (args.length == 2) {
		//
		// reads the XML source from the standard input
		//
		siena.publish(m.makeNotification(System.in));
	    } else {
		//
		// reads the XML sources from file passed through the
		// command line
		//
		for(int i = 2; i < args.length; ++i) 
		    siena.publish(m.makeNotification(args[i]));
	    }
	} catch (Exception ex) {
	    ex.printStackTrace();
	    System.exit(1);
	}
	System.exit(0);
    }
};

Simple subscriber of XML data

XMLSubscriber.java:

import siena.*;
import siena.sxml.*;
//
// a simple XML subscriber
//
class SimpleXMLSubscriber implements XMLNotifiable {
    //
    // does nothing but printing out the XML events it receives
    //
    public void notifyXml(String xml_event) {
	System.out.println("XML Event:\n" + xml_event);
    }

    //
    // does nothing at all with patterns of XML events
    //
    public void notifyXml(String[] xml_events) {};
}
//
// a simple subscriber
//
class SimpleSubscriber implements siena.Notifiable {
    //
    // extracts and prints the XML content from the Siena
    // notification, if the notification doesn't have any XML source,
    // prints the notification.
    //
    public void notify(Notification n) {
	String s;
	s = EventMap.getXmlText();
	if (s == null) s = n.toString();
	System.out.println("Event:\n" + s);
    }
    //
    // does nothing with patterns
    //
    public void notify(Notification[] events) {};
}

public class XMLSubscriber {
    public static void main(String args[]) {

	if (args.length != 1) {
	    System.err.println("Usage: TestXMLNotifiable ");
	    System.exit(1);
	}
	try {
	    ThinClient siena = new ThinClient(args[0]);

	    Filter f = new Filter();
	    f.addConstraint("name",Op.ANY,"");

	    XMLNotifiableWrapper wrapper;
	    wrapper = new XMLNotifiableWrapper(new SimpleXMLSubscriber());
	    
	    siena.subscribe(f, wrapper);
	    siena.subscribe(f, new SimpleSubscriber());
	    Thread.sleep(10000);
	    siena.unsubscribe(wrapper);
	    siena.shutdown();
	} catch (Exception ex) {
	    ex.printStackTrace();
	    System.exit(1);
	}
	System.exit(0);
    }
}

XML notification

swrelease.xml:

<!-- this is an example of an XML notification -->
<swrelease date="Nov 17 2001">
  <system name="DVS" version="1.3.1" footprint="52017"
          href="http://www.cs.colorado.edu/~carzanig/dvs/">
    <variance platform="linux2+i386"/>
    <variance platform="solaris2+sparc"/>
    <variance platform="solaris2+i386"/>
    <variance platform="osf1+alpha"/>
    <variance platform="win32+i386"/>
  </system>
  <download>
     <site href="http://www.cs.colorado.edu/~carzanig/dvs/"/>
     <site href="ftp://127.0.0.1/serl/dvs/software/"/>
  </download>
  <contact name="Antonio Carzaniga" href="mailto:carzanig@cs.colorado.edu"/>
  <changelog>
    <item type="feature">default behavior for the proxy map:
          addresses that are not mapped are used directly. This means
          that by default, every address maps into itself. Previously,
          DVS returned a failed connection.</item>

    <item type="bugfix" bugid="31415">machines with multiple IP
          addresses are now handled correctly by the proxy map. That
          is, DVS maps all the IP addresses corresponding to a
          hostname into the given proxy address.</item>
  </changelog>
</swrelease>

Sxml mapping specification

swrelease-map.sxml:

#
# example of a Sxml map
#
string date="/swrelease/@date";
string system="/swrelease/system/@name";
string version="/swrelease/system/@version";
int size="/swrelease/system/@footprint";
string platforms="/swrelease/system/variance/@platform" separator ",";
string uri="/swrelease/site/@href" last;
string changelog="/swrelease/changelog/item" xml;