You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by mr...@apache.org on 2006/05/01 23:38:03 UTC

svn commit: r398694 [9/9] - in /incubator/ode/trunk: ./ bpel-bom/ bpel-bom/src/ bpel-bom/src/main/ bpel-bom/src/main/java/ bpel-bom/src/main/java/org/ bpel-bom/src/main/java/org/apache/ bpel-bom/src/main/java/org/apache/ode/ bpel-bom/src/main/java/org/...

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/DOMUtils.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/DOMUtils.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/DOMUtils.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/DOMUtils.java Mon May  1 14:37:44 2006
@@ -0,0 +1,754 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils;
+
+import com.sun.org.apache.xerces.internal.dom.DOMOutputImpl;
+import com.sun.org.apache.xerces.internal.impl.Constants;
+import com.sun.org.apache.xml.internal.serialize.DOMSerializerImpl;
+import com.sun.org.apache.xml.internal.serialize.OutputFormat;
+import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.pool.BasePoolableObjectFactory;
+import org.apache.commons.pool.ObjectPool;
+import org.apache.commons.pool.PoolableObjectFactory;
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.w3c.dom.*;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Utility class for dealing with the Document Object Model (DOM).
+ */
+public class DOMUtils {
+
+  private static Log __log = LogFactory.getLog(DOMUtils.class);
+
+  /** The namespaceURI represented by the prefix <code>xmlns</code>. */
+  public static final String NS_URI_XMLNS = "http://www.w3.org/2000/xmlns/";
+
+  private static DocumentBuilderFactory __documentBuilderFactory ;
+  private static ObjectPool __documentBuilderPool;
+
+  static {
+    initDocumentBuilderPool();
+  }
+
+  /**
+   * Initialize the document-builder pool.
+   */
+  private static void initDocumentBuilderPool() {
+    DocumentBuilderFactory f = XMLParserUtils.getDocumentBuilderFactory();
+    f.setNamespaceAware(true);
+    __documentBuilderFactory = f;
+
+    PoolableObjectFactory pof = new BasePoolableObjectFactory() {
+      public Object makeObject() throws Exception {
+        if (__log.isDebugEnabled()) {
+          __log.debug("makeObject: Creating new DocumentBuilder.");
+        }
+
+        DocumentBuilder db = null;
+        synchronized (__documentBuilderFactory) {
+          try {
+            db = __documentBuilderFactory.newDocumentBuilder();
+//            db.setErrorHandler(new LoggingErrorHandler());
+          } catch (ParserConfigurationException e) {
+            __log.error(e);
+            throw new RuntimeException(e);
+          }
+        }
+        return db;
+      }
+
+      public void destroyObject(Object obj) throws Exception {
+        if (__log.isDebugEnabled())
+          __log.debug("destroyObject: Removing DocumentBuilder from pool: " + obj);
+      }
+    };
+
+    GenericObjectPool.Config poolCfg = new GenericObjectPool.Config();
+    poolCfg.maxActive = Integer.MAX_VALUE;
+    poolCfg.maxIdle = 20;
+    poolCfg.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
+    __documentBuilderPool = new GenericObjectPool(pof, poolCfg);
+  }
+
+  /**
+   * Returns the value of an attribute of an element. Returns null if the
+   * attribute is not found (whereas Element.getAttribute returns "" if an
+   * attrib is not found).
+   *
+   * @param el Element whose attrib is looked for
+   * @param attrName name of attribute to look for
+   *
+   * @return the attribute value
+   */
+  static public String getAttribute(Element el, String attrName) {
+    String sRet = null;
+    Attr attr = el.getAttributeNode(attrName);
+    if (attr != null) {
+      sRet = attr.getValue();
+    }
+    return sRet;
+  }
+  
+  static public String prettyPrint(Element e) throws IOException {
+    OutputFormat format = new OutputFormat(e.getOwnerDocument());  
+    format.setLineWidth(65);  
+    format.setIndenting(true);  
+    format.setIndent(2);  
+    StringWriter out = new StringWriter();
+    XMLSerializer serializer = new XMLSerializer(out, format);  
+    serializer.serialize(e); 
+    
+    return out.toString();
+  }
+
+  /**
+   * Returns the value of an attribute of an element. Returns null if the
+   * attribute is not found (whereas Element.getAttributeNS returns "" if an
+   * attrib is not found).
+   *
+   * @param el Element whose attrib is looked for
+   * @param namespaceURI namespace URI of attribute to look for
+   * @param localPart local part of attribute to look for
+   *
+   * @return the attribute value
+   */
+  static public String getAttributeNS(Element el, String namespaceURI,
+      String localPart) {
+    String sRet = null;
+    Attr attr = el.getAttributeNodeNS(namespaceURI, localPart);
+    if (attr != null) {
+      sRet = attr.getValue();
+    }
+    return sRet;
+  }
+
+  /**
+   * Concat all the text and cdata node children of this elem and return the
+   * resulting text.
+   *
+   * @param parentEl the element whose cdata/text node values are to be
+   *        combined.
+   *
+   * @return the concatanated string.
+   */
+  static public String getChildCharacterData(Element parentEl) {
+    if (parentEl == null) { return null; }
+    Node tempNode = parentEl.getFirstChild();
+    StringBuffer strBuf = new StringBuffer();
+    CharacterData charData;
+    while (tempNode != null) {
+      switch (tempNode.getNodeType()) {
+      case Node.TEXT_NODE:
+      case Node.CDATA_SECTION_NODE:
+        charData = (CharacterData) tempNode;
+        strBuf.append(charData.getData());
+        break;
+      }
+      tempNode = tempNode.getNextSibling();
+    }
+    return strBuf.toString();
+  }
+
+  /**
+   * DOCUMENTME
+   *
+   * @param el DOCUMENTME
+   * @param id DOCUMENTME
+   *
+   * @return DOCUMENTME
+   */
+  public static Element getElementByID(Element el, String id) {
+    if (el == null) { return null; }
+    String thisId = el.getAttribute("id");
+    if (id.equals(thisId)) { return el; }
+    NodeList list = el.getChildNodes();
+    for (int i = 0; i < list.getLength(); i++) {
+      Node node = list.item(i);
+      if (node instanceof Element) {
+        Element ret = getElementByID((Element) node, id);
+        if (ret != null) { return ret; }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Return the first child element of the given element. Null if no children
+   * are found.
+   *
+   * @param elem Element whose child is to be returned
+   *
+   * @return the first child element.
+   */
+  public static Element getFirstChildElement(Element elem) {
+    for (Node n = elem.getFirstChild(); n != null; n = n.getNextSibling()) {
+      if (n.getNodeType() == Node.ELEMENT_NODE) { return (Element) n; }
+    }
+    return null;
+  }
+
+  /**
+   * Given a prefix and a node, return the namespace URI that the prefix has
+   * been associated with. This method is useful in resolving the namespace
+   * URI of attribute values which are being interpreted as QNames. If prefix
+   * is null, this method will return the default namespace.
+   *
+   * @param context the starting node (looks up recursively from here)
+   * @param prefix the prefix to find an xmlns:prefix=uri for
+   *
+   * @return the namespace URI or null if not found
+   */
+  public static String getNamespaceURIFromPrefix(Node context, String prefix) {
+    short nodeType = context.getNodeType();
+    Node tempNode = null;
+    switch (nodeType) {
+    case Node.ATTRIBUTE_NODE: {
+      tempNode = ((Attr) context).getOwnerElement();
+      break;
+    }
+    case Node.ELEMENT_NODE: {
+      tempNode = context;
+      break;
+    }
+    default: {
+      tempNode = context.getParentNode();
+      break;
+    }
+    }
+    while ((tempNode != null) && (tempNode.getNodeType() == Node.ELEMENT_NODE)) {
+      Element tempEl = (Element) tempNode;
+      String namespaceURI = (prefix == null) ? getAttribute(tempEl, "xmlns")
+          : getAttributeNS(tempEl, NS_URI_XMLNS, prefix);
+      if (namespaceURI != null) {
+        return namespaceURI;
+      }
+      tempNode = tempEl.getParentNode();
+    }
+    return null;
+  }
+
+  /**
+   * Return the next sibling element of the given element. Null if no more
+   * sibling elements are found.
+   *
+   * @param elem Element whose sibling element is to be returned
+   *
+   * @return the next sibling element.
+   */
+  public static Element getNextSiblingElement(Element elem) {
+    for (Node n = elem.getNextSibling(); n != null; n = n.getNextSibling()) {
+      if (n.getNodeType() == Node.ELEMENT_NODE) { return (Element) n; }
+    }
+    return null;
+  }
+
+  /**
+   * DOCUMENTME
+   *
+   * @param el DOCUMENTME
+   * @param attrName DOCUMENTME
+   *
+   * @return DOCUMENTME
+   *
+   * @throws IllegalArgumentException DOCUMENTME
+   */
+  public static QName getQualifiedAttributeValue(Element el, String attrName)
+      throws IllegalArgumentException {
+    String attrValue = DOMUtils.getAttribute(el, attrName);
+    if (attrValue != null) {
+      int index = attrValue.indexOf(':');
+      String attrValuePrefix = (index != -1) ? attrValue.substring(0, index)
+          : null;
+      String attrValueLocalPart = attrValue.substring(index + 1);
+      String attrValueNamespaceURI = DOMUtils.getNamespaceURIFromPrefix(el,
+          attrValuePrefix);
+      if (attrValueNamespaceURI != null) {
+        return new QName(attrValueNamespaceURI, attrValueLocalPart);
+      }
+      throw new IllegalArgumentException("Unable to determine "
+            + "namespace of '"
+            + ((attrValuePrefix != null) ? (attrValuePrefix + ":") : "")
+            + attrValueLocalPart + "'.");
+    }
+    return null;
+  }
+
+  /**
+   * Count number of children of a certain type of the given element.
+   *
+   * @param elem the element whose kids are to be counted
+   * @param nodeType DOCUMENTME
+   *
+   * @return the number of matching kids.
+   */
+  public static int countKids(Element elem, short nodeType) {
+    int nkids = 0;
+    for (Node n = elem.getFirstChild(); n != null; n = n.getNextSibling()) {
+      if (n.getNodeType() == nodeType) {
+        nkids++;
+      }
+    }
+    return nkids;
+  }
+
+
+
+  /**
+   * This method traverses the DOM and grabs namespace declarations
+   * on parent elements with the intent of preserving them for children.  <em>Note
+   * that the DOM level 3 document method {@link Element#getAttribute(java.lang.String)}
+   * is not desirable in this case, as it does not respect namespace prefix
+   * bindings that may affect attribute values.  (Namespaces in DOM are
+   * uncategorically a mess, especially in the context of XML Schema.)</em>
+   * @param el the starting element
+   * @return a {@link Map} containing prefix bindings.
+   */
+  public static Map<String, String> getParentNamespaces(Element el) {
+    HashMap<String,String> pref = new HashMap<String,String>();
+    Map mine = getMyNamespaces(el);
+    Node n = el.getParentNode();
+    do {
+      if (n instanceof Element) {
+        Element l = (Element) n;
+        NamedNodeMap nnm = l.getAttributes();
+        int len = nnm.getLength();
+        for (int i = 0; i < len; ++i) {
+          Attr a = (Attr) nnm.item(i);
+          if (isNSAttribute(a)) {
+            String key = getNSPrefixFromNSAttr(a);            
+            String uri = a.getValue();
+            // prefer prefix bindings that are lower down in the tree.
+            if (pref.containsKey(key) || mine.containsKey(key)) continue;
+            pref.put(key, uri);
+          }
+        }
+      }
+      n = n.getParentNode();
+    } while (n != null && n.getNodeType() != Node.DOCUMENT_NODE);
+    return pref;
+  }
+
+  /**
+   * Construct a {@link NSContext} instance for the supplied element.
+   * @param el the <code>Element</code> to gather the namespace context for
+   * @return the <code>NSContext</code>
+   */
+  public static NSContext getMyNSContext(Element el) {
+    NSContext ns = new NSContext();
+    ns.register(getParentNamespaces(el));
+    ns.register(getMyNamespaces(el));
+    return ns;
+  }
+  
+  public static Map<String,String> getMyNamespaces(Element el) {
+    HashMap<String,String> mine = new HashMap<String,String>();
+    NamedNodeMap nnm = el.getAttributes();
+    int len = nnm.getLength();
+    for (int i=0; i < len; ++i) {
+      Attr a = (Attr) nnm.item(i);
+      if (isNSAttribute(a)) {
+        mine.put(getNSPrefixFromNSAttr(a),a.getValue());
+      }
+    }
+    return mine;
+  }
+  
+  /**
+   * Test whether an attribute contains a namespace declaration. 
+   * @param a an {@link Attr} to test.
+   * @return <code>true</code> if the {@link Attr} is a namespace declaration
+   */
+  public static boolean isNSAttribute(Attr a) {
+    assert a != null;
+    String s = a.getNamespaceURI();
+    return (s != null && s.equals(NS_URI_XMLNS));
+  }
+
+  /**
+   * Fetch the non-null namespace prefix from a {@link Attr} that declares
+   * a namespace.  (The DOM APIs will return <code>null</code> for a non-prefixed
+   * declaration.
+   * @param a the {@link Attr} with the declaration (must be non-<code>null</code).
+   * @return the namespace prefix or <code>&quot;&quot;</code> if none was
+   * declared, e.g., <code>xmlns=&quot;foo&quot;</code>.
+   */
+  public static String getNSPrefixFromNSAttr(Attr a) {
+    assert a != null;
+    assert isNSAttribute(a);
+    if (a.getPrefix() == null) {
+      return "";
+    }
+    return a.getName().substring(a.getPrefix().length()+1);
+  }
+
+  /**
+   * Convert a DOM node to a stringified XML representation.
+   */
+  static public String domToString(Node node) {
+    if (node == null) {
+      throw new IllegalArgumentException("Cannot stringify null Node!");
+    }
+
+    String value = null;
+    short nodeType = node.getNodeType();
+    if (nodeType == Node.ELEMENT_NODE || nodeType == Node.DOCUMENT_NODE) {
+      // serializer doesn't handle Node type well, only Element
+      DOMSerializerImpl ser = new DOMSerializerImpl();
+      ser.setParameter(Constants.DOM_NAMESPACES, Boolean.TRUE);
+      ser.setParameter(Constants.DOM_WELLFORMED, Boolean.FALSE );
+      ser.setParameter(Constants.DOM_VALIDATE, Boolean.FALSE);
+
+      // create a proper XML encoding header based on the input document;
+      // default to UTF-8 if the parent document's encoding is not accessible
+      String usedEncoding = "UTF-8";
+      Document parent = node.getOwnerDocument();
+      if (parent != null) {
+        String parentEncoding = parent.getXmlEncoding();
+        if (parentEncoding != null) {
+          usedEncoding = parentEncoding;
+        }
+      }
+
+      // the receiver of the DOM
+      DOMOutputImpl out = new DOMOutputImpl();
+      out.setEncoding(usedEncoding);
+
+      // we write into a String
+      StringWriter writer = new StringWriter(4096);
+      out.setCharacterStream(writer);
+
+      // out, ye characters!
+      ser.write(node, out);
+      writer.flush();
+
+      // finally get the String
+      value = writer.toString();
+    } else {
+      value = node.getNodeValue();
+    }
+    return value;
+  }
+
+  /**
+   * Convert a DOM node to a stringified XML representation.
+   */
+  static public String domToStringLevel2(Node node) {
+    if (node == null) {
+      throw new IllegalArgumentException("Cannot stringify null Node!");
+    }
+
+    String value = null;
+    short nodeType = node.getNodeType();
+    if (nodeType == Node.ELEMENT_NODE || nodeType == Node.DOCUMENT_NODE) {
+      // serializer doesn't handle Node type well, only Element
+      DOMSerializerImpl ser = new DOMSerializerImpl();
+      ser.setParameter(Constants.DOM_NAMESPACES, Boolean.TRUE);
+      ser.setParameter(Constants.DOM_WELLFORMED, Boolean.FALSE );
+      ser.setParameter(Constants.DOM_VALIDATE, Boolean.FALSE);
+
+      // the receiver of the DOM
+      DOMOutputImpl out = new DOMOutputImpl();
+      out.setEncoding("UTF-8");
+
+      // we write into a String
+      StringWriter writer = new StringWriter(4096);
+      out.setCharacterStream(writer);
+
+      // out, ye characters!
+      ser.write(node, out);
+      writer.flush();
+
+      // finally get the String
+      value = writer.toString();
+    } else {
+      value = node.getNodeValue();
+    }
+    return value;
+  }
+
+  /**
+   * Return the first child element of the given element which has the given
+   * attribute with the given value.
+   *
+   * @param elem the element whose children are to be searched
+   * @param attrName the attrib that must be present
+   * @param attrValue the desired value of the attribute
+   *
+   * @return the first matching child element.
+   */
+  public static Element findChildElementWithAttribute(Element elem,
+      String attrName, String attrValue) {
+    for (Node n = elem.getFirstChild(); n != null; n = n.getNextSibling()) {
+      if (n.getNodeType() == Node.ELEMENT_NODE) {
+        if (attrValue.equals(DOMUtils.getAttribute((Element) n, attrName))) { return (Element) n; }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Parse a String into a DOM.
+   *
+   * @param s DOCUMENTME
+   *
+   * @return DOCUMENTME
+   *
+   * @throws SAXException DOCUMENTME
+   * @throws IOException DOCUMENTME
+   */
+  static public Element stringToDOM(String s) throws SAXException, IOException {
+    return parse(new InputSource(new StringReader(s))).getDocumentElement();
+  }
+
+  /**
+   * Perform a naive check to see if a document is a WSDL document
+   * based on the root element name and namespace URI.
+   * @param d the {@link Document} to check
+   * @return <code>true</code> if the root element appears correct
+   */
+  public static boolean isWsdlDocument(Document d) {
+    Element e = d.getDocumentElement();
+    String uri = e.getNamespaceURI();
+    String localName = e.getLocalName();
+    if (uri == null || localName == null) { return false; }
+    return uri.equals(WSDL_NS) && localName.equals(WSDL_ROOT_ELEMENT);
+  }
+
+  /**
+   * Perform a naive check to see if a document is an XML schema document
+   * based on the root element name and namespace URI.
+   * @param d the {@link Document} to check
+   * @return <code>true</code> if the root element appears correct
+   */
+  public static boolean isXmlSchemaDocument(Document d) {
+    Element e = d.getDocumentElement();
+    String uri = e.getNamespaceURI();
+    String localName = e.getLocalName();
+    if (uri == null || localName == null) { return false; }
+    return uri.equals(XSD_NS) && localName.equals(XSD_ROOT_ELEMENT);
+  }
+
+  public static final String WSDL_NS = "http://schemas.xmlsoap.org/wsdl/";
+  public static final String WSDL_ROOT_ELEMENT = "definitions";
+  public static final String XSD_NS = "http://www.w3.org/2001/XMLSchema";
+  public static final String XSD_ROOT_ELEMENT = "schema";
+
+  /**
+   * @param el
+   */
+  public static void pancakeNamespaces(Element el) {
+    Map ns = getParentNamespaces(el);
+    Document d = el.getOwnerDocument();
+    assert d != null;
+    for (Object o : ns.keySet()) {
+      String key = (String) o;
+      String uri = (String) ns.get(key);
+      Attr a = d.createAttributeNS(NS_URI_XMLNS,
+              (key.length() != 0) ? ("xmlns:" + key) : ("xmlns"));
+      a.setValue(uri);
+      el.setAttributeNodeNS(a);
+    }
+  }
+
+  public static Document newDocument() {
+    DocumentBuilder db;
+    try {
+      db = borrow();
+    } catch (Exception ex) {
+      throw new RuntimeException("XML PARSE ERROR (NO PARSERS!)", ex);
+    }
+    try {
+      return db.newDocument();
+    } finally {
+      returnObject(db);
+    }
+  }
+
+  /**
+   * Parse an XML stream using the pooled document builder.
+   * @param inputStream input stream
+   * @return parsed XML document
+   */
+  public static Document parse(InputStream inputStream) throws SAXException, IOException {
+    return parse(new InputSource(inputStream));
+  }
+
+  /**
+   * Parse an XML document located using an {@link InputSource} using the
+   * pooled document builder.
+   */
+  public static Document parse(InputSource inputSource) throws SAXException,IOException{
+    DocumentBuilder db = borrow();
+    try {
+      return db.parse(inputSource);
+    } finally {
+      returnObject(db);
+    }
+
+  }
+
+  /**
+   * Borrow a {@link DocumentBuilder} to the pool.
+   */
+  private static synchronized DocumentBuilder borrow() throws SAXException {
+    try {
+      return (DocumentBuilder) __documentBuilderPool.borrowObject();
+    } catch (SAXException sae) {
+      throw sae;
+    } catch (Exception ex) {
+      throw new SAXException(ex);
+    }
+
+  }
+
+  /** Return the {@link DocumentBuilder} to the pool. */
+  private static synchronized void returnObject(DocumentBuilder db) {
+    try {
+      __documentBuilderPool.returnObject(db);
+    } catch (Exception ex) {
+      __log.debug("Error returning DocumentBuilder to object pool (ignoring).", ex);
+    }
+  }
+
+  /**
+   * Check that an element is empty, i.e., it contains no non-whitespace text or 
+   * elements as children.
+   * @param el the element
+   * @return <code>true</code> if the element is empty, <code>false</code> if not.
+   */
+  public static boolean isEmptyElement(Element el) {
+    NodeList nl = el.getChildNodes();
+    int len = nl.getLength();
+    for (int i=0; i < len; ++i) {
+      switch (nl.item(i).getNodeType()) {
+        case Node.CDATA_SECTION_NODE:
+        case Node.TEXT_NODE:
+          String s = nl.item(i).getNodeValue();
+          if (s != null && s.trim().length() > 0) {
+            return false;
+          }
+          break;
+        case Node.ELEMENT_NODE:
+          return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * @param el
+   */
+  public static QName getElementQName(Element el) {
+    return new QName(el.getNamespaceURI(),el.getLocalName());
+  }
+
+  /**
+   * Remove the child nodes under another node.
+   * @param target the <code>Node</code> to remove the children from.
+   */
+  public static void removeChildren(Node target) {
+    while (target.hasChildNodes()) {
+      target.removeChild(target.getFirstChild());
+    }
+  }
+
+  /**
+   * Drop the attributes from an element, except possibly an <code>xmlns</code>
+   * attribute that declares its namespace.
+   * @param target the element whose attributes will be removed.
+   * @param flag preserve namespace declaration
+   */
+  public static void removeAttributes(Element target, boolean flag) {
+    if (!target.hasAttributes()) {
+      return;
+    }
+    String prefix = target.getPrefix();
+    NamedNodeMap nnm = target.getAttributes();
+    Attr toPutBack = null;
+    if (flag) {
+      if (prefix== null) {
+        toPutBack = target.getAttributeNodeNS(NS_URI_XMLNS,"xmlns");
+      } else {
+        toPutBack = target.getAttributeNodeNS(NS_URI_XMLNS,"xmlns:" + prefix);
+      }
+      
+    }
+    while(nnm.getLength() != 0) {
+      target.removeAttributeNode((Attr) nnm.item(0));
+    }
+    if (toPutBack != null) {
+      target.setAttributeNodeNS(toPutBack);
+    }
+  }
+  
+  public static Element findChildByName(Element parent, QName name) {
+  	return findChildByName(parent, name, false);
+  }
+
+  public static Element findChildByName(Element parent, QName name, boolean recurse) {
+    if (parent == null)
+      throw new IllegalArgumentException("null parent");
+    if (name == null)
+      throw new IllegalArgumentException("null name");
+
+    NodeList nl = parent.getChildNodes();
+    for (int i = 0; i < nl.getLength(); ++i) {
+      Node c = nl.item(i);
+      if(c.getNodeType() != Node.ELEMENT_NODE)
+        continue;
+      if (new QName(c.getNamespaceURI(),c.getLocalName()).equals(name))
+        return (Element) c;
+    }
+    
+    if(recurse){
+      NodeList cnl = parent.getChildNodes();
+      for (int i = 0; i < cnl.getLength(); ++i) {
+        Node c = cnl.item(i);
+        if(c.getNodeType() != Node.ELEMENT_NODE)
+          continue;
+        Element result = findChildByName((Element)c, name, recurse);
+        if(result != null)
+          return result;
+      }
+    }
+    return null;
+  }
+
+  public static String getTextContent(Node node) {
+    for (int m = 0; m < node.getChildNodes().getLength(); m++) {
+      Node child = node.getChildNodes().item(m);
+      if (child.getNodeType() == Node.TEXT_NODE) {
+        String childText = child.getNodeValue().trim();
+        if (childText.length() > 0) return childText;
+      }
+    }
+    return null;
+  }
+
+  public static Element getElementContent(Node node) {
+    for (int m = 0; m < node.getChildNodes().getLength(); m++) {
+      Node child = node.getChildNodes().item(m);
+      if (child.getNodeType() == Node.ELEMENT_NODE) return (Element) child;
+    }
+    return null;
+  }
+
+}
\ No newline at end of file

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/NSContext.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/NSContext.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/NSContext.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/NSContext.java Mon May  1 14:37:44 2006
@@ -0,0 +1,179 @@
+/*
+ * File: $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ * 
+ */
+
+package org.apache.ode.utils;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.*;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.ode.utils.stl.*;
+
+/**
+ * A simple in-memory implementation of the {@link NamespaceContext} interface
+ * with fairly generic applicability. This class allows clients to manipulate
+ * the context through publicly accessible methods, and provides serialization
+ * support.
+ * 
+ * @see NamespaceContext
+ */
+public class NSContext implements NamespaceContext, Externalizable {
+  private static final long serialVersionUID = 1L;
+
+  /** Class-level logger. */
+  private static final Log __log = LogFactory.getLog(NSContext.class);
+
+  /** Prefix-to-URI map. */
+  private HashMap<String, String> _prefixToUriMap = new HashMap<String, String>();
+
+  public NSContext() {
+  }
+
+  public NSContext(NSContext map) {
+    _prefixToUriMap.putAll(map._prefixToUriMap);
+  }
+
+  /**
+   * @see NamespaceContext#getNamespaceURI(java.lang.String)
+   */
+  public String getNamespaceURI(String prefix) {
+    return _prefixToUriMap.get(prefix);
+  }
+
+  /**
+   * @see NamespaceContext#getPrefix(java.lang.String)
+   */
+  public String getPrefix(String uri) {
+    Iterator i = getPrefixes(uri);
+
+    if (i.hasNext()) {
+      return (String)i.next();
+    }
+
+    return null;
+  }
+
+  /**
+   * @see NamespaceContext#getPrefixes
+   */
+  @SuppressWarnings("unchecked")
+  public Iterator getPrefixes(final String uri) {
+    return new TransformIterator(new FilterIterator(_prefixToUriMap.entrySet().iterator(),
+        new CompositeUnaryFunction(new EqualsUnaryFunction(uri), CollectionsX.ufnMapEntry_getValue)),
+        CollectionsX.ufnMapEntry_getKey);
+  }
+
+  /**
+   * Get all the prefixes with a URI mapping in this context
+   * 
+   * @return{@link Set} of prefix {@link String}s with a URI mapping in this
+   *         context
+   */
+  public Set<String> getPrefixes() {
+    return Collections.unmodifiableSet(_prefixToUriMap.keySet());
+  }
+
+  /**
+   * Get all the URIs with a prefix mapping in this context
+   * 
+   * @return{@link Set} of URI {@link String}s with a prefix mapping in this
+   *         context
+   */
+  public Set<String> getUriSet() {
+    return new HashSet<String>(_prefixToUriMap.values());
+  }
+
+  /**
+   * @see Externalizable#readExternal(java.io.ObjectInput)
+   */
+  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+    int numKeys = in.readInt();
+
+    for (int i = 0; i < numKeys; ++i) {
+      String prefix = in.readUTF();
+      String uri = in.readUTF();
+      _prefixToUriMap.put(prefix, uri);
+    }
+
+    if (__log.isTraceEnabled()) {
+      __log.trace("readExternal: contents=" + _prefixToUriMap);
+    }
+  }
+
+  /**
+   * Add a prefix to URI mapping to this context.
+   * 
+   * @param prefix
+   *          prefix
+   * @param uri
+   *          URI
+   */
+  public void register(String prefix, String uri) {
+    if (__log.isTraceEnabled()) {
+      __log.trace("register(prefix=" + prefix + ", uri=" + uri + ")");
+    }
+
+    _prefixToUriMap.put(prefix, uri);
+  }
+
+  /**
+   * Register a set of URI mappings at once.
+   * 
+   * @param prefixMapping
+   *          set (map rather) of prefix-to-URI mappings.
+   */
+  public void register(Map<String, String> prefixMapping) {
+    if (__log.isTraceEnabled()) {
+      __log.trace("register(prefixmappings=" + prefixMapping + ")");
+    }
+
+    _prefixToUriMap.putAll(prefixMapping);
+  }
+
+  /**
+   * @see Externalizable#writeExternal(java.io.ObjectOutput)
+   */
+  public void writeExternal(ObjectOutput out) throws IOException {
+    if (__log.isTraceEnabled()) {
+      __log.trace("writeExternal: contents=" + _prefixToUriMap);
+    }
+
+    out.writeInt(_prefixToUriMap.size());
+
+    for (Iterator i = _prefixToUriMap.entrySet().iterator(); i.hasNext();) {
+      Map.Entry me = (Map.Entry)i.next();
+      out.writeUTF((String)me.getKey());
+      out.writeUTF((String)me.getValue());
+    }
+  }
+
+  public QName derefQName(String qname) {
+    int idx = qname.indexOf(':');
+
+    if (idx == -1) {
+      return new QName(getNamespaceURI(null), qname);
+    }
+    else {
+      String prefix = qname.substring(0, idx);
+      String localname = qname.substring(idx + 1);
+      String uri = getNamespaceURI(prefix);
+
+      if (uri == null) {
+        return null;
+      }
+
+      return new QName(uri, localname);
+    }
+  }
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/NamespaceStack.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/NamespaceStack.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/NamespaceStack.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/NamespaceStack.java Mon May  1 14:37:44 2006
@@ -0,0 +1,275 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils;
+
+import java.util.EmptyStackException;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.xml.namespace.QName;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+
+/**
+ * <p>
+ * This is a utility for a SAX <code>ContentHandler</code> implementation to use in
+ * tracking namespace declarations during a parse.  The assumption is that the
+ * handler has access to the full stream of events relevant to managing the
+ * declarations.  The primary use case is the resolution of <code>String</code>s, 
+ * e.g., from attribute values or element content, to <code>QName</code> objects.
+ * </p>
+ */
+public class NamespaceStack {
+
+  private Frame _current;
+  
+  /**
+   * <p>
+   * Construct a new instance with the bare minimum bindings for the
+   * <code>xmlns</code>, <code>xml</code>, and empty prefixes.  Note that the empty
+   * prefix is bound to the empty (non-<code>null</code>) URI.
+   * </p>
+   */
+  public NamespaceStack() {
+    _current = new Frame();
+    /*
+     * As per the Namespaces in XML Errata:
+     * http://www.w3.org/XML/xml-names-19990114-errata
+     */
+    _current.declarePrefix("xmlns","http://www.w3.org/2000/xmlns/");
+    /*
+     * As per the Namespaces in XML Rec:
+     * http://www.w3.org/TR/1999/REC-xml-names-19990114
+     */
+    _current.declarePrefix("xml","http://www.w3.org/XML/1998/namespace");
+    /*
+     * As per the Namespaces in XML Rec:
+     * http://www.w3.org/TR/1999/REC-xml-names-19990114
+     */
+    _current.declarePrefix("","");
+  }
+  
+  /**
+   * <p>
+   * Convert the current stack of contexts into a single <code>NSContext</code>.
+   * </p>
+   * @return the <code>NSContext</code> instance
+   */
+  public NSContext toNSContext() {
+    NSContext n = new NSContext();
+    for (Frame f = _current;f != null; f=f._parent) {
+      if (f._bindings == null) continue;
+      for (Iterator it = f._bindings.keySet().iterator();it.hasNext();) {
+        String pfx = (String) it.next();
+        if (n.getNamespaceURI(pfx) == null) {
+          n.register(pfx, f._bindings.get(pfx));
+        }
+      }
+    }
+    return n;
+  }
+  
+  /**
+   * <p>
+   * Push a fresh context onto the stack.  This method should be called somewhere in
+   * the body of a <code>startElement()</code>, as it represents the namespace
+   * resolution context for the events that occur between that event and the
+   * corresponding <code>endElement()</code>.
+   * </p>
+   * @see org.xml.sax.ContentHandler
+   */
+  public void pushNewContext() {
+    _current = new Frame(_current);
+  }
+  
+  /**
+   * <p>
+   * Pop a context from the stack.  This method should be called somewhere in the
+   * body of an <code>endElement</code>, as it clears the context that was used for
+   * namespace resolution within the body of the corresponding element.
+   * </p>
+   * @see org.xml.sax.ContentHandler
+   */
+  public void pop() {
+    if (_current._parent == null) {
+      throw new EmptyStackException();
+    }
+    _current = _current._parent;
+  }
+  
+  /**
+   * <p>
+   * Declare a new prefix binding.  This binding will supercede a binding with the
+   * same prefix in the same scope.  As a crutch, <code>null</code> arguments may be
+   * passed and will be interpreted as <code>&quot;&quot;</code>.  Note that binding
+   * a non-empty prefix to an empty URI is not permitted in XML 1.0 but is not
+   * flagged as an error by the method.
+   * </p>
+   * @param prefix the prefix to bind
+   * @param uri the URI to bind it to
+   */
+  public void declarePrefix(String prefix, String uri) {
+    _current.declarePrefix(prefix==null?"":prefix, uri==null?"":uri);
+  }
+  
+  /**
+   * <p>
+   * Retrieve the URI bound to the supplied prefix or <code>null</code> if no URI
+   * is bound to the supplied prefix.  As a crutch, a <code>null</code> argument
+   * may be passed and will be interpreted as the empty prefix
+   * (<code>&quot;&quot;</code>).
+   * </p>
+   * @returns the URI or <code>null</code> if no URI is bound.
+   */
+  public String getNamespaceUri(String prefix) {
+    return _current.getNamespaceURI(prefix==null?"":prefix);
+  }
+  
+  /**
+   * <p>
+   * Fire the events for the current frame's prefixes into a <code>ContentHandler</code>. 
+   * </p>
+   * @param ch the target <code>ContentHandler</code>
+   * @throws SAXException if the target method does.
+   */
+  public void startPrefixMappings(ContentHandler ch) throws SAXException {
+    _current.startPrefixMappings(ch);
+  }
+  
+  /**
+   * <p>
+   * Fire the events for the current frame's prefixes into a <code>ContentHandler</code>.
+   * </p>
+   * @param ch the target <code>ContentHandler</code>.
+   * @throws SAXException if the target method does.
+   */
+  public void endPrefixMappings(ContentHandler ch) throws SAXException {
+    _current.endPrefixMappings(ch);
+  }
+  
+  /**
+   * <p>
+   * Allocate and declare a new namespace prefix for the current context that uses
+   * the supplied &quot;hint&quot; as a start.  The algorithm used will defer to an
+   * existing binding, then try the hint, then use a variant of the hint until it
+   * finds an available prefix.
+   * </p>
+   * @param hint a hint as to the desired prefix or <code>null</code> if any prefix
+   * will do.
+   * @param uri the URI to bind to the prefix.
+   * @return the suggested prefix.
+   */
+  public String allocatePrefix(String hint, String uri) {
+    String pfx = getPrefix(uri);
+    if (pfx == null) {
+      hint = hint==null?"ns":hint;
+      String u = getNamespaceUri(hint);
+      if (u == null) {
+        declarePrefix(hint,uri);
+        pfx = hint;
+      } else if (u.equals(uri)) {
+        pfx = hint;
+      } else {
+        // ??
+      }
+    }
+    return pfx;
+  }
+  
+  public String getPrefix(String uri) {
+    return toNSContext().getPrefix(uri);
+  }
+  
+  /**
+   * <p>
+   * Derference the prefix on a QName in <code>String</code> form and return a Java
+   * <code>QName</code> object.
+   * </p>
+   * @param qname the QName in string form.
+   * @return the dereferenced <code>QName</code>.
+   * @throws IllegalArgumentException if a <code>null</code> argument is passed,
+   * a malformed argument (e.g., <code>:foo</code> or <code>foo:</code>) is passed,
+   * or if the prefix cannot be resolved to a URI.
+   */
+  public QName dereferenceQName(String qname) {
+    if (qname == null) {
+      throw new IllegalArgumentException("Unable to dereference <null> as a QName.");
+    }
+    int pos = qname.indexOf(':');
+    QName qn;
+    if (pos == qname.length() - 1 || pos == 0) {
+      throw new IllegalArgumentException("\"" + qname + "\" is a malformed QName.");
+    } else if (pos == -1) {
+      qn = new QName (getNamespaceUri(""),qname);
+    } else {
+      String uri = getNamespaceUri(qname.substring(0,pos));
+      if (uri == null) {
+        throw new IllegalArgumentException("No URI is bound to " +
+            qname.substring(0,pos) + ".");
+      }
+      qn = new QName(uri,qname.substring(pos+1));
+    }
+    return qn;
+  }
+  
+  private class Frame {
+    
+    Frame _parent;
+    
+    HashMap<String,String> _bindings;
+    
+    Frame() {
+      // This space intentionally left blank.
+    }
+    
+    Frame(Frame parent) {
+      _parent = parent;
+    }
+   
+    void startPrefixMappings(ContentHandler ch) throws SAXException {
+      if (_bindings != null) {
+        for(Iterator it = _bindings.keySet().iterator();it.hasNext();) {
+          String prefix = (String) it.next();
+          ch.startPrefixMapping(prefix, _bindings.get(prefix));
+        }
+      }
+    }
+    
+    void endPrefixMappings(ContentHandler ch) throws SAXException {
+      if (_bindings != null) {
+        for (Iterator it = _bindings.keySet().iterator();it.hasNext();) {
+          ch.endPrefixMapping((String) it.next());
+        }
+      }
+    }
+    
+    void declarePrefix(String prefix, String uri) {
+      if (_bindings == null) {
+        _bindings = new HashMap<String,String>();
+      }
+      _bindings.put(prefix,uri);
+    }
+    
+    String getPrefix(String uri) {
+      return "";
+    }
+
+    
+    String getNamespaceURI(String prefix) {
+      String uri = null;
+      if (_bindings != null) {
+        uri = _bindings.get(prefix);
+      }
+      if (uri == null) {
+        uri= _parent==null ? null:(_parent.getNamespaceURI(prefix));
+      }
+      return uri;
+    }
+    
+  }
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/SystemConfigurationException.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/SystemConfigurationException.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/SystemConfigurationException.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/SystemConfigurationException.java Mon May  1 14:37:44 2006
@@ -0,0 +1,53 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils;
+
+/**
+ * An exception to encapsulate issues with system configuration. Examples
+ * include the inability to find required services (e.g., XML parsing).
+ */
+public class SystemConfigurationException extends RuntimeException {
+
+	private static final long serialVersionUID = -2330515949287155695L;
+
+	/**
+	 * Construct a new instance with the specified message.
+	 * 
+	 * @param message
+	 *            a descriptive message.
+	 * @see RuntimeException#RuntimeException(java.lang.String)
+	 */
+	public SystemConfigurationException(String message) {
+		super(message);
+	}
+
+	/**
+	 * Construct a new instance with the specified message and a
+	 * {@link Throwable} that triggered this exception.
+	 * 
+	 * @param message
+	 *            a descriptive message
+	 * @param cause
+	 *            the cause
+	 * @see RuntimeException#RuntimeException(java.lang.String,
+	 *      java.lang.Throwable)
+	 */
+	public SystemConfigurationException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	/**
+	 * Construct a new instance with the specified {@link Throwable} as the root
+	 * cause.
+	 * 
+	 * @param cause
+	 *            the cause
+	 * @see RuntimeException#RuntimeException(java.lang.Throwable)
+	 */
+	public SystemConfigurationException(Throwable cause) {
+		super(cause);
+	}
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/XMLParserUtils.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/XMLParserUtils.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/XMLParserUtils.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/XMLParserUtils.java Mon May  1 14:37:44 2006
@@ -0,0 +1,277 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils;
+
+import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl;
+import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl;
+import com.sun.org.apache.xerces.internal.parsers.DOMParser;
+import com.sun.org.apache.xerces.internal.parsers.SAXParser;
+import com.sun.org.apache.xml.internal.serialize.OutputFormat;
+import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
+import org.xml.sax.*;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.SAXParserFactory;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+
+/**
+ * A collection of utility methods for the Apache Xerces XML parser.
+ */
+public class XMLParserUtils {
+  
+  public static final String NAMESPACES_SAXF = 
+    "http://xml.org/sax/features/namespaces";
+  public static final String VALIDATION_SAXF =
+    "http://xml.org/sax/features/validation";
+  public static final String SCHEMA_V_XERCESF =
+    "http://apache.org/xml/features/validation/schema";
+  private static final String XERCES_P_ROOT =
+    "http://apache.org/xml/properties/schema/";
+  private static final String EXTERNAL_SCHEMA_LOC_XERCESP = 
+    XERCES_P_ROOT + "external-schemaLocation";
+  private static final String EXTERNAL_SCHEMA_NNS_LOC_XERCESP = 
+    XERCES_P_ROOT + "external-noNamespaceSchemaLocation";
+
+  /**
+   * Set the necessary system properties to use the correct XML parsers
+   */
+  static {
+    System.setProperty("javax.xml.parsers.SAXParserFactory", 
+        "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
+    System.setProperty("javax.xml.parsers.DocumentBuilderFactory", 
+        "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"); 
+  }
+
+  /**
+   * <p>
+   * Get the 'correct' implementation of a JAXP <code>SAXParserFactory</code>; this is
+   * intended to ensure that local implementations (e.g., Crimson) don't sneak into
+   * the mix.
+   * </p>
+   * @return the Xerces-specific implementaiton
+   */
+  public static SAXParserFactory getSAXParserFactory() {
+    return new SAXParserFactoryImpl();
+  }
+  
+  /**
+   * <p>
+   * Get the 'correct' implementation of a JAXP <code>DocumentBuilderFactory</code>;
+   * this is intended to ensure that local implementations (e.g., Crimson) don't
+   * sneak into the mix.
+   * </p>
+   * @return the Xerces-specific implementation
+   */
+  public static DocumentBuilderFactory getDocumentBuilderFactory() {
+    return new DocumentBuilderFactoryImpl();
+  }
+  
+  /**
+   * Set the <code>namespaces</code> SAX property on the supplied
+   * <code>XMLReader</code>.
+   * @param xr the <code>XMLReader</code> to apply the feature to.
+   */
+  public static void setNamespaces(XMLReader xr) {
+    try {
+      xr.setFeature(NAMESPACES_SAXF, true);
+    } catch (SAXException snse) {
+      throw new SystemConfigurationException(snse);
+    }
+  }
+  
+  /**
+   * @return a Xerces-specific <code>XMLReader</code> instance.
+   */
+  public static XMLReader getXMLReader() {
+    return new SAXParser();
+  }
+  
+  /**
+   * @return a Xerces-specific DOM parser.
+   */
+  public static DOMParser getDOMParser() {
+    return new DOMParser();
+  }
+  
+  /**
+   * <p>
+   * Specify an external schema location and turn on validation via setting features
+   * and properties.
+   * </p>
+   * @param xr the XMLReader to apply the features and properties to.
+   * @param namespace the namespace URI of the schema to validate, with the empty
+   * string or <code>null</code> serving to represent the empty namespace.
+   * @param u the URL (or relative URL) that contains the schema.
+   * @throws SAXNotSupportedException if one of the underlying feature/property
+   * settings does.
+   * @throws SAXNotRecognizedException if one of the underlying feature/property
+   * settings does.
+   */
+  public static void setExternalSchemaURL(XMLReader xr, String namespace, String u)
+      throws SAXNotRecognizedException, SAXNotSupportedException
+  {
+    xr.setFeature(NAMESPACES_SAXF,true);
+    if (namespace != null && namespace.length() > 0) {
+      xr.setProperty(EXTERNAL_SCHEMA_LOC_XERCESP, namespace + " " + u);
+    } else {
+      xr.setProperty(EXTERNAL_SCHEMA_NNS_LOC_XERCESP, u);
+    }
+    xr.setFeature(VALIDATION_SAXF,true);
+    xr.setFeature(SCHEMA_V_XERCESF,true);    
+  }
+  
+  /**
+   * <p>
+   * Specify an external schema location and turn on validation via setting features
+   * and properties.
+   * </p>
+   * @param dp the <code>DOMParser</code> to apply the features and properties to.
+   * @param namespace the namespace URI of the schema to validate, with the empty
+   * string or <code>null</code> serving to represent the empty namespace.
+   * @param u the URL or relative URL that contains the schema.
+   * @throws SAXNotSupportedException if one of the underlying feature/property
+   * settings does.
+   * @throws SAXNotRecognizedException if one of the underlying feature/property
+   * settings does.
+   */  
+  public static void setExternalSchemaURL(DOMParser dp, String namespace, String u)
+      throws SAXNotRecognizedException, SAXNotSupportedException
+  {
+    dp.setFeature(VALIDATION_SAXF,true);
+    dp.setFeature(SCHEMA_V_XERCESF,true);
+    if (namespace != null && namespace.length() > 0) {
+      dp.setProperty(EXTERNAL_SCHEMA_LOC_XERCESP, namespace + " " + u);
+    } else {
+      dp.setProperty(EXTERNAL_SCHEMA_NNS_LOC_XERCESP, u);
+    }
+  }
+  
+  /**
+   * <p>
+   * Add a namespace/URL pair to the mapping between namespaces and the schemas used
+   * to validate elements in them.  Adding a pair for a namespace that's already
+   * bound will result in overwriting the URL previously bound.
+   * </p>
+   * @param xr
+   * @param namespace
+   * @param u
+   * @throws SAXNotRecognizedException
+   * @throws SAXNotSupportedException
+   */
+  public static void addExternalSchemaURL(XMLReader xr, String namespace, String u)
+    throws SAXNotRecognizedException,SAXNotSupportedException
+  {
+    xr.setFeature(VALIDATION_SAXF,true);
+    xr.setFeature(SCHEMA_V_XERCESF,true);
+    if (namespace == null || namespace.length() == 0) {
+      setExternalSchemaURL(xr,namespace,u);
+      return;
+    }    
+    String s = (String) xr.getProperty(EXTERNAL_SCHEMA_LOC_XERCESP);
+    if (s == null) {
+      setExternalSchemaURL(xr,namespace,u);
+      return;
+    }
+    StringTokenizer st = new StringTokenizer(s);
+    HashMap<String,String> namespaces = new HashMap<String,String>();
+    while (st.hasMoreTokens()) {
+      String key = st.nextToken();
+      if (!st.hasMoreTokens()) {
+        throw new RuntimeException("Property has been misconfigured; expected an " +
+            "even number of tokens.  Value was: " + s);
+      }
+      String value = st.nextToken();
+      namespaces.put(key,value);
+    }
+    namespaces.put(namespace,u);
+    StringBuffer sb = new StringBuffer();
+    Iterator it = namespaces.keySet().iterator();
+    while (it.hasNext()) {
+      String ns = (String) it.next();
+      sb.append(ns);
+      sb.append(' ');
+      sb.append(namespaces.get(ns));
+      if (it.hasNext()) {
+        sb.append(' ');
+      }
+    }
+    xr.setProperty(EXTERNAL_SCHEMA_LOC_XERCESP,sb.toString());
+    xr.setFeature(VALIDATION_SAXF,true);
+    xr.setFeature(SCHEMA_V_XERCESF,true);     
+  }
+  
+  /**
+   * <p>
+   * Add a namespace/URL pair to the mapping between namespaces and the schemas used
+   * to validate elements in them.  Adding a pair for a namespace that's already
+   * bound will result in overwriting the URL previously bound.
+   * </p>
+   * @param dp the <code>DOMParser</code> to apply the features and properties to.
+   * @param namespace the namespace URI of the schema to validate, with the empty
+   * string or <code>null</code> serving to represent the empty namespace.
+   * @param u the URL or relative URL that contains the schema.
+   * @throws SAXNotSupportedException if one of the underlying feature/property
+   * settings does.
+   * @throws SAXNotRecognizedException if one of the underlying feature/property
+   * settings does.
+   */
+  public static void addExternalSchemaURL(DOMParser dp, String namespace, String u)
+    throws SAXNotRecognizedException,SAXNotSupportedException
+  {
+    dp.setFeature(VALIDATION_SAXF,true);
+    dp.setFeature(SCHEMA_V_XERCESF,true);
+    if (namespace == null || namespace.length() == 0) {
+      setExternalSchemaURL(dp,namespace,u);
+      return;
+    }
+    String s = (String) dp.getProperty(EXTERNAL_SCHEMA_LOC_XERCESP);
+    if (s == null) {
+      setExternalSchemaURL(dp,namespace,u);
+      return;
+    }
+    StringTokenizer st = new StringTokenizer(s);
+    HashMap<String,String> namespaces = new HashMap<String,String>();
+    while (st.hasMoreTokens()) {
+      String key = st.nextToken();
+      if (!st.hasMoreTokens()) {
+        throw new RuntimeException("Property has been misconfigured; expected an " +
+            "even number of tokens.  Value was: " + s);
+      }
+      String value = st.nextToken();
+      namespaces.put(key,value);
+    }
+    namespaces.put(namespace,u);
+    StringBuffer sb = new StringBuffer();
+    Iterator it = namespaces.keySet().iterator();
+    while (it.hasNext()) {
+      String ns = (String) it.next();
+      sb.append(ns);
+      sb.append(' ');
+      sb.append(namespaces.get(ns));
+      if (it.hasNext()) {
+        sb.append(' ');
+      }
+    }
+    dp.setProperty(EXTERNAL_SCHEMA_LOC_XERCESP,sb.toString());
+    dp.setFeature(VALIDATION_SAXF,true);
+    dp.setFeature(SCHEMA_V_XERCESF,true);     
+  }
+
+
+  public static ContentHandler getXercesSerializer(OutputStream os) {
+    XMLSerializer serializer =  new XMLSerializer();
+    OutputFormat format = new OutputFormat();
+    format.setPreserveSpace(true);
+    format.setOmitDocumentType(true);
+    serializer.setOutputFormat(format);
+    serializer.setOutputByteStream(os);
+    return serializer;
+
+  }
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/msg/CommonMessages.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/msg/CommonMessages.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/msg/CommonMessages.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/msg/CommonMessages.java Mon May  1 14:37:44 2006
@@ -0,0 +1,41 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+
+package org.apache.ode.utils.msg;
+
+public class CommonMessages extends MessageBundle {
+
+  public String strError() {
+    return this.format("Error");
+  }
+
+  public String strFatal() {
+    return this.format("Fatal");
+  }
+
+  public String strInfo() {
+    return this.format("Info");
+  }
+
+  public String strWarning() {
+    return this.format("Warning");
+  }
+
+  public String msgFileNotFound(String string) {
+    return this.format("File not found: {0}", string);
+  }
+
+  public String msgCannotWriteToFile(String string) {
+    return this.format("Unable to write to file \"{0}\";"
+        + " it may be a directory or otherwise unwritable.", string);
+  }
+
+  public String msgCannotReadFromFile(String string) {
+    return this.format("Unable to read from file \"{0}\";"
+        + " it may be missing, a directory, or otherwise unreadable.", string);
+  }
+
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/msg/MessageBundle.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/msg/MessageBundle.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/msg/MessageBundle.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/msg/MessageBundle.java Mon May  1 14:37:44 2006
@@ -0,0 +1,55 @@
+package org.apache.ode.utils.msg;
+
+import java.text.MessageFormat;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+public abstract class MessageBundle extends ResourceBundle {
+
+  public static <T extends MessageBundle> T getMessages(Class<T> bundleInterface) {
+    return getMessages(bundleInterface, Locale.getDefault());
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <T extends MessageBundle> T getMessages(Class<T> bundleInterface, Locale locale) {
+    // TODO maybe catch MissingResourceException here
+    return (T)ResourceBundle.getBundle(bundleInterface.getName(), locale, bundleInterface.getClassLoader());
+  }
+
+  public MessageBundle() {
+    super();
+  }
+
+  /**
+   * Generate a "todo" message.
+   * @return todo message string
+   */
+  protected String todo() {
+    Exception ex = new Exception();
+    ex.fillInStackTrace();
+    return ex.getStackTrace()[1].getMethodName() + ": NO MESSAGE (TODO)";
+  }
+  
+  protected Object handleGetObject(String key) {
+    throw new UnsupportedOperationException();
+  }
+
+  public Enumeration<String> getKeys() {
+    throw new UnsupportedOperationException();
+  }
+
+  protected String format(String message) {
+    return message;
+  }
+
+  protected String format(String message, Object... args) {
+    if (args == null || args.length == 0) {
+      return message;
+    }
+    else {
+      return new MessageFormat(message).format(args);
+    }
+  }
+
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/BinaryFunction.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/BinaryFunction.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/BinaryFunction.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/BinaryFunction.java Mon May  1 14:37:44 2006
@@ -0,0 +1,10 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils.stl;
+
+public interface BinaryFunction {
+  Object apply(Object x, Object y);
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/CollectionsX.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/CollectionsX.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/CollectionsX.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/CollectionsX.java Mon May  1 14:37:44 2006
@@ -0,0 +1,207 @@
+/*
+ * File: $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ * 
+ */
+
+package org.apache.ode.utils.stl;
+
+import java.util.*;
+
+
+/**
+ * Useful extensions to the java.util.Collections class.
+ */
+public class CollectionsX {
+
+  public static UnaryFunction<Map.Entry,Object> ufnMapEntry_getKey = new UnaryFunction<Map.Entry,Object>() {
+    public Object apply(Map.Entry x) {
+      return x.getKey();
+    }
+  };
+
+  public static UnaryFunction<Map.Entry,Object> ufnMapEntry_getValue = new UnaryFunction<Map.Entry,Object>() {
+    public Object apply(Map.Entry x) {
+      return x.getValue();
+    }
+  };
+
+  public static <T> void apply(Collection<T> coll, UnaryFunction<T, ?> f) {
+    apply(coll.iterator(), f);
+  }
+
+  public static <T> void apply(Iterator<T> i, UnaryFunction<T,?> f) {
+    while (i.hasNext()) {
+      f.apply(i.next());
+    }
+  }
+
+  public static <T> void apply(Collection<T> coll, UnaryFunctionEx<T,?> f) throws Exception {
+    apply(coll.iterator(), f);
+  }
+
+  public static <T> void apply(Iterator<T> i, UnaryFunctionEx<T, ?> f) throws Exception {
+    while (i.hasNext()) {
+      f.apply(i.next());
+    }
+  }
+
+  /**
+   * Find an element in a colletion satisfying a condition. The condition is
+   * given in the form of a unary function which returns a non-<code>false</code>
+   * value when the condition is satisfied. The first object in the collection
+   * matching the condition is returned.
+   * 
+   * @param coll
+   *          the collection to search through
+   * @param f
+   *          the test to apply to the collection elements
+   * 
+   * @return the first object in the collection (coll) which, satisfies the
+   *         condition (f)
+   */
+  public static <T> T find_if(Collection<T> coll, MemberOfFunction<T> f) {
+    return find_if(coll.iterator(), f);
+  }
+
+  /**
+   * Find an element in a collection satisfying a condition.
+   *
+   * @param i the iterator to iterate with
+   * @param f the test to apply to the elements
+   *
+   * @return the first object enumerated by the iterator (i) which satisfies
+   *         the condition (f)
+   *
+   * @see #find_if(java.util.Collection, org.apache.ode.utils.stl.MemberOfFunction)
+   */
+  public static <T> T find_if(Iterator<T> i, MemberOfFunction<T> f) {
+    while (i.hasNext()) {
+      T x = i.next();
+
+      if (f.isMember(x)) {
+        return x;
+      }
+    }
+
+    return null;
+  }
+
+  public static <T> Collection<T> insert(Collection<T> coll, Enumeration<? extends T> e) {
+    while (e.hasMoreElements()) {
+      coll.add(e.nextElement());
+    }
+    return coll;
+  }
+
+  public static <T> Collection<T> insert(Collection<T> coll, Iterator<? extends T> i) {
+    while (i.hasNext()) {
+      coll.add(i.next());
+    }
+    return coll;
+  }
+
+  public static <T> Collection<T> insert(Collection<T> coll, Collection<? extends T> src) {
+    return insert(coll, src.iterator());
+  }
+
+  /**
+   * Remove elements from collection based on the results of specified unary
+   * function. An element will be deleted if <code>f.isMember(element)
+   * </code> returns <code>true</code>. So: <em>coll' = { x : x el-of coll
+   * AND f(x) == false }</em>
+   *
+   * @param coll the collection from which to remove elements
+   * @param f the function to apply
+   *
+   * @return coll, for convenience
+   */
+  public static <T> Collection<T> remove_if(Collection<T> coll, MemberOfFunction<T> f) {
+    Iterator<T> i = coll.iterator();
+
+    while (i.hasNext()) {
+      if (f.isMember(i.next())) {
+        i.remove();
+      }
+    }
+
+    return coll;
+  }
+
+  /**
+   * Transform a collection with a unary function. Roughly speaking dest = {
+   * f(a) : a el-of src }
+   *
+   * @param dest the empty (mutable) collection to transform into
+   * @param src the collection to transform from
+   * @param f the unary function to apply
+   *
+   * @return dest, for convenience
+   */
+  public static <T,V extends T,E> Collection<T> transform(Collection<T> dest, Collection<E> src,
+                                     UnaryFunction<E,V> f) {
+    Iterator<E> i = src.iterator();
+
+    while (i.hasNext()) {
+      dest.add(f.apply(i.next()));
+    }
+
+    return dest;
+  }
+
+  public static <T,V extends T,E> Collection<T> transform(Collection<T> dest, Collection<E> src,
+      UnaryFunctionEx<E,V> f)  throws Exception {
+    Iterator<E> i = src.iterator();
+
+    while (i.hasNext()) {
+      dest.add(f.apply(i.next()));
+    }
+
+    return dest;
+  }
+  
+  public static <T,V extends T, E> Collection<T> transform(Collection<T> dest, Enumeration<E> i,
+                                     UnaryFunction<E,V> f) {
+    while (i.hasMoreElements()) {
+      dest.add(f.apply(i.nextElement()));
+    }
+    return dest;
+  }
+
+  public static <T, S extends T> Collection filter(Collection<T> dest, Collection<S> source, MemberOfFunction<S> function) {
+    return filter(dest, source.iterator(), function);
+  }
+
+  public static <T, S extends T> Collection<T> filter(Collection<T> dest, Iterator<S> source, MemberOfFunction<S> function) {
+    while (source.hasNext()) {
+      S next = source.next();
+      if (function.isMember(next)) {
+        dest.add(next);
+      }
+    }
+    return dest;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <S, T extends S> Collection<T> filter(Collection<T> newList, Iterator<S> iterator, Class<T> t) {
+    while (iterator.hasNext()) {
+      S next = iterator.next();
+      if (t.isAssignableFrom(next.getClass())){
+        newList.add((T)next);
+      }
+    }
+    return newList;
+  }
+
+  /**
+   * Filter a collection by member class.
+   * @param src source collection
+   * @param aClass requested class
+   * @return collection consisting of the members of the input that are assignable to the given class
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> Collection<T> filter(Collection src, final Class<T> aClass) {
+    return filter(new ArrayList<T>(src.size()), src.iterator(), aClass);
+  }
+
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/CompositeUnaryFunction.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/CompositeUnaryFunction.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/CompositeUnaryFunction.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/CompositeUnaryFunction.java Mon May  1 14:37:44 2006
@@ -0,0 +1,22 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+
+package org.apache.ode.utils.stl;
+
+public class CompositeUnaryFunction<E,V,T> implements UnaryFunction<E,V> {
+  private UnaryFunction<T,V> _f;
+  private UnaryFunction<E,T> _g;
+
+  public CompositeUnaryFunction(UnaryFunction<T,V> f, UnaryFunction<E,T> g) {
+    _f = f;
+    _g = g; 
+  }
+
+  public V apply(E x) {
+    return _f.apply(_g.apply(x));
+  }
+
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/EnumerationIterator.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/EnumerationIterator.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/EnumerationIterator.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/EnumerationIterator.java Mon May  1 14:37:44 2006
@@ -0,0 +1,35 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils.stl;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+
+
+/**
+ * Adapter class, adapting <code>Enumeration</code> objects to the
+ * <code>Iterator</code> interface.
+ */
+public class EnumerationIterator<T> implements Iterator<T> {
+  private Enumeration<T> _enum;
+
+  public EnumerationIterator(Enumeration<T> e) {
+    _enum = e;
+  }
+
+  public boolean hasNext() {
+    return _enum.hasMoreElements();
+  }
+
+  public T next() {
+    return _enum.nextElement();
+  }
+
+  public void remove() {
+    throw new UnsupportedOperationException("Method remove() not supported.");
+  }
+
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/EqualsUnaryFunction.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/EqualsUnaryFunction.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/EqualsUnaryFunction.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/EqualsUnaryFunction.java Mon May  1 14:37:44 2006
@@ -0,0 +1,28 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils.stl;
+
+/**
+ * Equality comparison unary function, compares against a constant value.
+ * 
+ * <p>
+ * Created on Feb 4, 2004 at 5:15:38 PM.
+ * </p>
+ *
+ * @author Maciej Szefler <a href="mailto:mbs@fivesight.com">mbs</a>
+ */
+public class EqualsUnaryFunction<T> extends MemberOfFunction {
+  private T _c;
+
+  public EqualsUnaryFunction(T c) {
+    _c = c;
+  }
+
+  public boolean isMember(Object x) {
+    return _c.equals(x);
+  }
+
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/FilterIterator.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/FilterIterator.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/FilterIterator.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/FilterIterator.java Mon May  1 14:37:44 2006
@@ -0,0 +1,73 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils.stl;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+
+/**
+ * Filtering {@link Iterator} implementation.
+ * 
+ * <p>
+ * Created on Feb 4, 2004 at 4:48:14 PM.
+ * </p>
+ *
+ * @author Maciej Szefler <a href="mailto:mbs@fivesight.com">mbs</a>
+ */
+public class FilterIterator<T> implements Iterator<T> {
+  private UnaryFunction<T,Boolean> _mf;
+  private Iterator<T> _i;
+  private T _next;
+
+  public FilterIterator(Iterator<T> i, UnaryFunction<T,Boolean> mf) {
+    _i = i;
+    _mf = mf;
+  }
+
+  public boolean hasNext() {
+    return doNext();
+  }
+
+  public T next() {
+    if (doNext()) {
+      T ret = _next;
+      _next = null;
+
+      return ret;
+    }
+
+    throw new NoSuchElementException("No more elements.");
+  }
+
+  public void remove() {
+    // Force loading the next object.
+    if (doNext()) {
+      _next = null;
+      _i.remove();
+    }
+
+    throw new NoSuchElementException("No more elements.");
+  }
+
+  private boolean doNext() {
+    if (_next != null) {
+      return true;
+    }
+
+    while (_i.hasNext()) {
+      T next = _i.next();
+
+      if (_mf.apply(next) == Boolean.TRUE) {
+        _next = next;
+
+        return true;
+      }
+    }
+
+    return false;
+  }
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/IteratorEnumeration.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/IteratorEnumeration.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/IteratorEnumeration.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/IteratorEnumeration.java Mon May  1 14:37:44 2006
@@ -0,0 +1,26 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils.stl;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+
+public class IteratorEnumeration<T> implements Enumeration<T> {
+  private Iterator<T> _iter;
+
+  public IteratorEnumeration(Iterator<T> i) {
+    _iter = i;
+  }
+
+  public boolean hasMoreElements() {
+    return _iter.hasNext();
+  }
+
+  public T nextElement() {
+    return _iter.next();
+  }
+
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/MemberOfFunction.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/MemberOfFunction.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/MemberOfFunction.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/MemberOfFunction.java Mon May  1 14:37:44 2006
@@ -0,0 +1,38 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils.stl;
+
+/**
+ * Interface used for defining object filters/selectors, classes that are used
+ * to determine whether a given object belong in a set.
+ * 
+ * <p>
+ * Created on Feb 4, 2004 at 4:48:55 PM.
+ * </p>
+ *
+ * @author Maciej Szefler <a href="mailto:mbs@fivesight.com">mbs</a>
+ */
+public abstract class MemberOfFunction<E> implements UnaryFunction<E,Boolean> {
+  /**
+   * A unary function that tests whether an element is the member of a set.
+   * @param o element to test
+   * @return <code>true</code> if element is a member
+   */
+  public abstract boolean isMember(E o);
+
+  /**
+   * Implementation of {@link UnaryFunction} method defering to
+   * {@link #isMember(E)}.
+   * @param x element to test
+   * @return {@link Boolean.TRUE} if isMemeber returns <code>true</code>,
+   *         <code>false</code> otherwise
+   */
+  public final Boolean apply(E x) {
+    return isMember(x)
+           ? Boolean.TRUE
+           : Boolean.FALSE;
+  }
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/TransformIterator.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/TransformIterator.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/TransformIterator.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/TransformIterator.java Mon May  1 14:37:44 2006
@@ -0,0 +1,54 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils.stl;
+
+import java.util.Iterator;
+
+
+/**
+ * Transforming {@link Iterator} implementation; these iterators apply a unary
+ * function to each object before it is returned.
+ * 
+ * <p>
+ * Created on Feb 4, 2004 at 4:48:14 PM.
+ * </p>
+ *
+ * @author Maciej Szefler <a href="mailto:mbs@fivesight.com">mbs</a>
+ */
+public class TransformIterator<E,V> implements Iterator<V> {
+  private UnaryFunction<E,V> _txform;
+  private Iterator<E> _i;
+
+  public TransformIterator(Iterator<E> i, UnaryFunction<E,V> txForm) {
+    _i = i;
+    _txform = txForm;
+  }
+
+  /**
+   * DOCUMENTME
+   *
+   * @return DOCUMENTME
+   */
+  public boolean hasNext() {
+    return _i.hasNext();
+  }
+
+  /**
+   * DOCUMENTME
+   *
+   * @return DOCUMENTME
+   */
+  public V next() {
+    return _txform.apply(_i.next());
+  }
+
+  /**
+   * DOCUMENTME
+   */
+  public void remove() {
+    _i.remove();
+  }
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/UnaryFunction.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/UnaryFunction.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/UnaryFunction.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/UnaryFunction.java Mon May  1 14:37:44 2006
@@ -0,0 +1,10 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils.stl;
+
+public interface UnaryFunction<E,V> extends UnaryFunctionEx<E,V> {
+  V apply(E x); 
+}

Added: incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/UnaryFunctionEx.java
URL: http://svn.apache.org/viewcvs/incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/UnaryFunctionEx.java?rev=398694&view=auto
==============================================================================
--- incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/UnaryFunctionEx.java (added)
+++ incubator/ode/trunk/utils/src/main/java/org/apache/ode/utils/stl/UnaryFunctionEx.java Mon May  1 14:37:44 2006
@@ -0,0 +1,10 @@
+/*
+ * File:      $RCSfile$
+ * Copyright: (C) 1999-2005 FiveSight Technologies Inc.
+ *
+ */
+package org.apache.ode.utils.stl;
+
+public interface UnaryFunctionEx<E,V> {
+  V apply(E x) throws Exception;
+}