Code-Stümpfe für Nachrichten-Handler erzeugen

(Auszug aus "XSLT Kochbuch" von Sal Mangano)

Problem

Sie möchten ein Skelett Ihrer Nachrichten-Handler generieren.

Lösung

Das folgende Stylesheet erzeugt ein einfaches Skelett, das zu einem gegebenen Prozessnamen den entsprechenden Code-Stumpf (engl. stub code) generiert:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <!-- Gibt an, für welchen Prozess Handler generiert werden sollen -->
  <xsl:param name="process"/>
  <!-- Gibt an, für welche Message Handler generiert werden sollen. Der Spezialwert %ALL% bezeichnet alle Messages. -->
  <xsl:param name="message" select=" '%ALL%' "/>
  <!-- Das Zielverzeichnis -->
  <xsl:variable name="message-dir" select=" 'messages' "/>
  <xsl:variable name="directory-sep" select=" '/' "/>
  <xsl:variable name="include-ext" select=" '.h' "/>
  <xsl:template match="MessageRepository">
    <xsl:choose>
      <xsl:when test="$message='%ALL%'"  >
        <xsl:apply-templates select="Messages/Message[Receivers/ProcessRef = $process]"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="Messages/Message[Receivers/ProcessRef = $process and Name=$message]"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template match="Message">
    <xsl:document href="{concat(Name,'.h')}">
      <xsl:call-template name="makeHeader"/>
    </xsl:document>
    <xsl:document href="{concat(Name,'.cpp')}">
      <xsl:call-template name="makeSource"/>
    </xsl:document>
  </xsl:template>
  <xsl:template name="makeHeader">
  #ifndef <xsl:value-of select="Name"/>_h
  #define <xsl:value-of select="Name"/>_h

  #include &lt;transport/MessageHandler.h&gt;

  // Vorwärtsdeklarationen
  class <xsl:value-of select="DataTypeName"/> ;
  /*!TODO:  Hier weitere Vorwärtsdeklarationen einfügen.*/

  class <xsl:value-of select="Name"/> : public MessageHandler
  {
  public:
    <xsl:value-of select="Name"/>(const <xsl:value-of select="DataTypeName"/>& data) ;
    bool process( ) ;
  private:

    const <xsl:value-of select="DataTypeName"/>& m_Data ;
  } ;

  #endif
  </xsl:template>
  <xsl:template name="makeSource">
  #include &lt;messages/<xsl:value-of select="Name"/>.h&gt;

  /*!TODO:  Hier weitere Includes einfügen. */

    <xsl:value-of select="Name"/>::<xsl:value-of select="Name"/>(const
        <xsl:value-of select="DataTypeName"/>& data)
      : m_Data(data)
    {
    }
    bool <xsl:value-of select="Name"/>::process( )
    {
        /*!TODO:  Hier Nachrichten-Handler-Code einfügen. */
        return true;
    }
  </xsl:template>
</xsl:stylesheet>

Dieses Stylesheet generiert für jede Nachricht, die es bearbeitet, eine Header- und eine Quelldatei (siehe auch die beiden folgenden Beispiele).

Beispiel: AddStockOrder.h

#ifndef ADD_STOCK_ORDER_h
#define ADD_STOCK_ORDER_h

#include <transport/MessageHandler.h>

// Vorwärtsdeklarationen
class AddStockOrderData ;
/*!TODO:  Insert addition forward declarations here.*/

class ADD_STOCK_ORDER : public MessageHandler
{
public:
    ADD_STOCK_ORDER(const AddStockOrderData& data) ;
    bool process() ;
private:

    const AddStockOrderData& m_Data ;
} ;

#endif

Beispiel: AddStockOrder.cpp

#include <messages/ADD_STOCK_ORDER.h>

/*!TODO:  Hier weitere Includes einfügen.*/

ADD_STOCK_ORDER::ADD_STOCK_ORDER(const AddStockOrderData& data)
  : m_Data(data)
{
}

bool ADD_STOCK_ORDER::process()
{
  /*!TODO:  Hier Nachrichten-Handler-Code einfügen. */
  return true;
}

Diskussion

Vieles von dem, was ein Entwickler so macht, ist von der Struktur her etwas, was sich immer wiederholt, aber in der Substanz immer etwas anderes. Mit anderen Worten: Wir schreiben Unmengen an vorgefertigtem Code, der im jeweils aktuellen Kontext spezialisiert wird. Das Ausführen jeder Art von sich wiederholender Arbeit führt zu Langeweile, Langeweile führt zu Ablenkung, und Ablenkung führt zu Fehlern. Wenn Sie die sich wiederholenden Teile Ihres Codes generieren, können Sie sich auf die wichtigen Teile konzentrieren.

Werkzeuge, die Code mit TODO-Abschnitten generieren, werden oftmals auch Wizards genannt. Der hier gezeigte Nachrichten-Handler-Wizard ist ein sehr einfaches Beispiel dieser Gattung. Einige kommerziell verfügbare Wizards generieren gleich die Struktur einer ganzen Anwendung. Es ist nicht klar, ob XSLT so weit skaliert, dass man damit Wizards dieser Größenordnung erzeugen könnte. Für Generatoren von einfachen Code-Stümpfen allerdings, deren Eingabe aus XML besteht, ist XSLT anderen Sprachen, inklusive Perl, vorzuziehen. Viele Perl-Fanatiker würden diese Aussage nicht unterschreiben, weil sie die Verarbeitung von XML nur als eine andere Form von Textverarbeitung betrachten (und natürlich wissen wir alle, dass Perl unbestritten als König der textverarbeitenden Sprachen gilt). Man kann aber das gewichtige Argument anführen, dass XML-Verarbeitung keine Verarbeitung von Text ist, sondern von Bäumen, die Textknoten enthalten. Und als solche transformiert XSLT Bäume flinker als Perl. Nichtsdestotrotz können Perl und XSLT ein Team bilden, in dem beide ihr Bestes einbringen, wie im Kapitel XSLT erweitern und einbetten demonstriert wird. Es enthält außerdem eine XSLT-Erweiterung, die den störenden Wortreichtum rein XSLT-basierter Generatoren beseitigt.

  

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © 2006 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT Kochbuch" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

O'Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de