<?xml version="1.0" encoding="UTF-8" ?>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
 |                                                                           |
 | o:XML is published under the GNU General Public Licence                   |
 |   (see http://www.gnu.org/licenses/licenses.html#GPL).                    |
 |                                                                           |
 | A copy of the licence agreement (gpl.txt) must be part of any             |
 |   redistribution of any form.                                             |
 |                                                                           |
 | o:XML was created by Martin Klang <mars@pingdynasty.com>.                 |
 |                                                                           |
 | For more information please see:                                          |
 |   http://www.o-xml.org/                                                   |
 |                                                                           |
 +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<xsl:stylesheet version="1.0" xmlns:o="http://www.o-xml.org/lang/"
		xmlns:UML="org.omg.xmi.namespace.UML" 
		xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <o:do>
      <xsl:apply-templates select="//UML:Model"/>
    </o:do>
  </xsl:template>

  <!-- template that creates a stub function body -->
  <xsl:template match="UML:Operation" mode="function-body">
    <o:do>
      <o:log msg="in function: {@name}"/>
      <xsl:comment> insert code here! </xsl:comment>
    </o:do>
  </xsl:template>

  <xsl:template match="UML:Package">
    <xsl:variable name="module-name" select="@name"/>
    <o:module name="{$module-name}">
<!--      <xsl:copy-of select="@xmi.id"/> -->
      <xsl:apply-templates/>
    </o:module>
  </xsl:template>

  <xsl:template match="UML:Class[@name]|UML:Interface[@name]|UML:DataType[@name]">
    <xsl:variable name="type-name" select="@name"/>
    <o:type name="{$type-name}">
<!--      <xsl:copy-of select="@xmi.id"/> -->
      <xsl:apply-templates select="@visibility"/>
      <xsl:apply-templates/>
    </o:type>
  </xsl:template>

  <!-- type variable definition -->
  <xsl:template match="UML:Attribute[@name]">
    <xsl:variable name="type">
      <xsl:apply-templates select="UML:StructuralFeature.type"/>
    </xsl:variable>
    <o:variable name="{@name}" type="{$type}">
<!--      <xsl:copy-of select="@xmi.id"/> -->
      <xsl:apply-templates select="@visibility"/>
    </o:variable>
  </xsl:template>

  <xsl:template match="UML:StructuralFeature.type">
    <xsl:apply-templates select="UML:DataType|UML:Class" mode="name"/>
  </xsl:template>

  <!-- type function definition -->
  <xsl:template match="UML:Operation[@name]">
    <o:function name="{@name}">
<!--      <xsl:copy-of select="@xmi.id"/> -->
      <xsl:apply-templates select="@visibility"/>
      <xsl:apply-templates select="UML:BehavioralFeature.parameter/UML:Parameter[@kind = 'return']"/>
      <xsl:apply-templates select="UML:BehavioralFeature.parameter/UML:Parameter[@kind = 'in']"/>
      <xsl:apply-templates select="." mode="function-body"/>
    </o:function>
  </xsl:template>

  <xsl:template match="UML:Parameter[@name and @kind = 'in']">
    <xsl:variable name="type">
<!--      <xsl:copy-of select="@xmi.id"/> -->
      <xsl:apply-templates select="UML:Parameter.type"/>
    </xsl:variable>
    <o:param name="{@name}" type="{$type}"/>
  </xsl:template>

  <xsl:template match="UML:Parameter[@name and @kind = 'return']">
    <xsl:attribute name="type">
      <xsl:apply-templates select="UML:Parameter.type"/>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="UML:Parameter.type">
    <xsl:apply-templates select="UML:DataType|UML:Class" mode="name"/>
  </xsl:template>

  <!-- parent type reference - resolve to a parent element -->
  <xsl:template match="UML:GeneralizableElement.generalization">
    <xsl:variable name="type">
      <xsl:apply-templates select="UML:Generalization" mode="name"/>
    </xsl:variable>    
    <o:parent name="{$type}">
<!--       <xsl:copy-of select="@xmi.id"/> -->
    </o:parent>
  </xsl:template>

  <!-- de-referencing -->
  <xsl:template match="*[@xmi.idref]" mode="name">
    <xsl:variable name="ref" select="@xmi.idref"/>
    <xsl:apply-templates select="//*[@xmi.id = $ref]" mode="name"/>
  </xsl:template>

  <!-- data type definition -->
  <xsl:template match="UML:DataType[@xmi.id]" mode="name">
    <xsl:value-of select="@name"/>
  </xsl:template>

  <!-- inheritance definition - resolve the name of the parent type -->
  <xsl:template match="UML:Generalization[@xmi.id]" mode="name">
    <xsl:apply-templates select="UML:Generalization.parent/UML:Class" mode="name"/>
  </xsl:template>

  <xsl:template match="UML:Class[@xmi.id]|UML:Interface[@xmi.id]" mode="name">
    <xsl:value-of select="@name"/>
  </xsl:template>

  <xsl:template match="@visibility">
    <xsl:attribute name="access"><xsl:value-of select="."/></xsl:attribute>
  </xsl:template>

  <xsl:template match="text()"/>

</xsl:stylesheet>
