You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tuscany.apache.org by Frank Budinsky <fr...@ca.ibm.com> on 2006/04/20 19:41:03 UTC

SDO MetaData configuration model

Hi guys,

Here is the schema of the configuration model that I have in mind that SDO 
clients can use to register their metadata:

<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="org.apache.tuscany.sdo/metadata"
    xmlns:metadata="org.apache.tuscany.sdo/metadata">

    <element name="sdoMetaDataGroup" type="metadata:SDOMetaDataGroup"/>

    <complexType name="SDOMetaDataGroup">
        <sequence>
            <element name="javaMetaData" type="metadata:JavaMetaData" 
maxOccurs="unbounded" minOccurs="0"/>
            <element name="xsdMetaData" type="metadata:XSDMetaData" 
maxOccurs="unbounded" minOccurs="0"/>
            <element name="typeMetaData" type="metadata:TypeMetaData" 
maxOccurs="unbounded" minOccurs="0"/>
        </sequence>
    </complexType>

    <complexType name="JavaMetaData">
        <attribute name="factoryInterface" type="string" use="optional"/>
        <attribute name="typeInterface" type="string" use="optional"/>
    </complexType>

    <complexType name="XSDMetaData">
        <attribute name="location" type="string" use="required"/>
    </complexType>

    <complexType name="TypeMetaData">
        <attribute name="location" type="string" use="required"/>
    </complexType>

</schema>

Using this model, users can register 1 or more SDO models, generated or 
dynamic ones, using an instance of SDOMetaDataGroup, something like this:

<metadata:sdoMetaDataGroup 
xmlns:metadata="org.apache.tuscany.sdo/metadata">
  <javaMetaData 
factoryInterface="com.example.noemf.simple.SimpleFactory"/>
  <!-- TBD <javaMetaData typeInterface="com.example.simple.Quote"/> -->
  <xsdMetaData location="/quote.xsd"/>
  <typeMetaData location="/customer.sdo"/>
</metadata:sdoMetaDataGroup>

Notice that there are 4 (currently only 3 are working) ways to describe 
your metadata:

1) Specifying a Java factory interface - this registers all the types 
supported by the factory.
2) By specifying a Java interface for a DataObject type - TBD
3) By specifying the location of an XMLSchema (.xsd) file defining the 
types.
4) By specifying the location of a serialized SDO model (.sdo) file.

To register the set of metadata described in the group, you simply load 
the instance and call the register() method on SDOMetaDataGroup, like 
this:

  XMLDocument doc = XMLHelper.INSTANCE.load(aMetaDataStream);
  SDOMetaDataGroup metadataGroup = (SDOMetaDataGroup)doc.getRootObject();
  metadataGroup.register(aTypeHelper);

The register() method looks something like this:

  public void register(TypeHelper typeHelper)
  {
    try
    {
      ClassLoader classLoader = 
(ClassLoader)AccessController.doPrivileged(new PrivilegedAction()
        {
          public Object run()
          {
            return Thread.currentThread().getContextClassLoader();
          }
        });
      register(typeHelper, classLoader);
    }
    catch (SecurityException e)
    {
    }
  }

  public void register(TypeHelper typeHelper, ClassLoader classLoader)
  {
    try
    {
      for (Iterator iter = getJavaMetaData().iterator(); iter.hasNext();)
      {
        JavaMetaData metadata = (JavaMetaData)iter.next();
        String factoryInterface = metadata.getFactoryInterface();
        if (factoryInterface != null)
        {
          Class factoryInterfaceClass = 
classLoader.loadClass(factoryInterface);
          SDOUtil.registerStaticTypes(factoryInterfaceClass);
        }
        else
        {
          String typeInterface = metadata.getTypeInterface();
          Class typeInterfaceClass = classLoader.loadClass(typeInterface);
          // TODO: introspect and register the type
        }
      }

      XSDHelper xsdHelper = SDOUtil.createXSDHelper(typeHelper);
      for (Iterator iter = getXsdMetaData().iterator(); iter.hasNext();)
      {
        XSDMetaData metadata = (XSDMetaData)iter.next();
        URL url = getClass().getResource(metadata.getLocation());
        InputStream inputStream = url.openStream();
        xsdHelper.define(inputStream, url.toString());
      }

      XMLHelper xmlHelper = SDOUtil.createXMLHelper(typeHelper);
      for (Iterator iter = getTypeMetaData().iterator(); iter.hasNext();)
      {
        TypeMetaData metadata = (TypeMetaData)iter.next();
        URL url = getClass().getResource(metadata.getLocation());
        InputStream inputStream = url.openStream();
        XMLDocument xmlDocument = xmlHelper.load(inputStream);
        Types types = (Types)xmlDocument.getRootObject();
        typeHelper.define(types.getTypeList());
      }
    }
    catch (Exception e)
    {
    }
  }
 
Please let me know what you think, and if you have any ideas or 
suggestions for improvement. I recognize that in the future, this will 
probably be expanded and generalized, but I wanted to start with something 
simple for now.

Frank.

P.S. here's what quote.xsd and customer.sdo look like (used in the example 
above).


quote.xsd
=========

<xsd:schema 
  targetNamespace="http://www.example.com/simple"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:simple="http://www.example.com/simple"> 
 
   <xsd:element name="stockQuote" type="simple:Quote"/>

   <xsd:complexType name="Quote">
       <xsd:sequence>
          <xsd:element name="symbol" type="xsd:string"/>
          <xsd:element name="companyName" type="xsd:string"/>
          <xsd:element name="price" type="xsd:decimal"/>
          <xsd:element name="open1" type="xsd:decimal"/>
          <xsd:element name="high" type="xsd:decimal"/>
          <xsd:element name="low" type="xsd:decimal"/>
          <xsd:element name="volume" type="xsd:double"/>
          <xsd:element name="change1" type="xsd:double"/>
          <xsd:element name="quotes" type="simple:Quote" minOccurs="0" 
maxOccurs="unbounded"/>
       </xsd:sequence>
   </xsd:complexType>

</xsd:schema>


customer.sdo
============

<sdo:types>
  <sdo:type xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:sdo="commonj.sdo"
      name="Customer" uri="http://example.com/customer">
    <sdo:property name="custNum" type="commonj.sdo#//Int"/>
    <sdo:property name="firstName" type="commonj.sdo#//String"/>
    <sdo:property name="lastName" type="commonj.sdo#//String"/>
  </sdo:type>
</sdo:types>