Sep 232007
 

Eine Java Serverapplikation muss oft in verschiedene Umgebungen (auch als Raum bezeichnet) installiert werden. Oft gibt es eine Testumgebeung, eine für die Integration und Fachtests, eine Schulungsumgebung und letztendlich eine Produktivumgebung. Für jede Umgebung müssen oft die Konfigurationsdateien und auch Deployment-Deskriptoren angepasst werden.

Gerade die Deployment-Deskriptoren wie “web.xml” (im WAR), “application.xml” (im EAR) unterscheiden sich marginal. Wäre es da nicht toll nur eine Deskriptor-Datei im Versionskontrollsystem zu halten und nur die marginale Änderungen mittels XSLT vorzunehmen. Natürlich wäre es das! ;-)


Vorteile wären:

  • der geringere Änderungsaufwand – es gibt nur einen Deploymentdeskriptor
  • die Unterschiede sind in der XSLT-Datei klar erkenntlich

im build prozess mit ant aus dem einen xml immer das spezifische für die umgebung erstellen

Im Buildprozess mit Ant kann der Deployment-Deskriptor mittels Standard-Ant-Task “xslt” erstellt werden:

<target name="__create_webxml_rootserver_prod">
  <xslt
    reloadstylesheet="true"
    in="${src.web.dir}/WEB-INF/web.xml"
    out="${temp.dir}/web.xml"
    style="${configs.rootserver_prod.dir}/war/WEB-INF/web.xml.xsl"/>
</target>

Das folgende Beispiel einer XSLT-Datei zeigt die Umgebungsspezifische Anpassung eines “web.xml” Deskriptors (für JEE Web Applikationen). Es werden Kontext-Parameter ergänzt und der Wert eines Kontext-Parameters angepasst:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:jee="http://java.sun.com/xml/ns/javaee"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!--
    change value of param 'facelets.DEVELOPMENT'
    -->
  <xsl:template match="jee:context-param[jee:param-name='facelets.DEVELOPMENT']/jee:param-value/text()">
    <xsl:text>false</xsl:text>
  </xsl:template>

  <!--
    add context params before first context param
   -->
  <xsl:template match="jee:context-param[1]">
    <context-param>
      <param-name>org.ajax4jsf.ENCRYPT_RESOURCE_DATA</param-name>
      <param-value>true</param-value>
    </context-param>

    <context-param>
      <param-name>org.ajax4jsf.ENCRYPT_PASSWORD</param-name>
      <param-value>DENKSTE</param-value>
    </context-param>

    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Aufpassen muss man mit dem Default-XML-Namespace in den zu transformierenden XML-Dateien. Dieser Default-XML-Namespace wird mittels “xmlns=” vergeben und sorgt dafür, dass man im XSLT mittels XPath Probleme bekommt die gewünschten XML-Elemente zu matchen. Daher wird im dargestellten XSLT der Präfix “jee” verwendet.

Im Grunde sollte dies mit XSLT 2.0 einfacher gehen. Siehe XSLT 2.0 QNames ohne Präfix. Dabei muss einfach das Attribut “xpath-default-namespace” zum Beispiel am obersten Element im Stylesheet angegeben werden. So in diesem Beispiel:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xpath-default-namespace="http://java.sun.com/xml/ns/javaee"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

Leider scheint auch der neueste Xalan-Prozessor das nicht zu können. Bitte belehrt mich jemand eines besseren. Xalan kann man in den Ant-Task “xslt” einbinden:

<target name="__xsl-webxml-rootserver-test">
  <xslt
    reloadstylesheet="true"
    in="${src.web.dir}/WEB-INF/web.xml"
    out="${temp.dir}/web.xml"
    classpath="${lib-build.dir}/xalan.jar"
    style="${configs.rootserver_test.dir}/war/WEB-INF/web.xml.xsl">

    <factory name="org.apache.xalan.processor.TransformerFactoryImpl">
      <attribute name="http://xml.apache.org/xalan/features/optimize" value="true"/>
    </factory>
  </xslt>
</target>

Fazit: Mittels dieses Ansatzes lässt sich der Aufwand beim Pflegen / Erweitern von Deployment-Deskriptoren bei gleichbleibender Flexibilität reduzieren. Mehrere Umgebungen können mit einem Deployment-Deskriptor, welcher durch XSL-Transformation adaptiert wird, betrieben werden. Dieser Ansatz ist sicher auch für Weblogics Domänenkonfiguration “config.xml” oder ähnliches denkbar.

  One Response to “web.xml Deployment-Deskriptor mit XSLT an verschiedene Umgebungen anpassen”

  1. […] und somit das Ein- und Ausschalten von FacesTrace nicht immer manuell umändern muss ist auf sophisticated-it zu lesen. Dort wird beschrieben wie man mit XSLT verschiedene Konfigurationen dynamisch […]

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>