You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 7 Next »

An old blogpost prompted me to try and devise a more current and elegant method of compiling the EAR deployment descriptor (application.xml) from an Ivy resolution report. Being a novice to XSLT use and syntax I chose to base this transformation/translation on the default Ivy report templates provided with the latest distribution (at the time of this writing that is Ivy version 2.2.0).

Using the wealth of information available from the resolution report in combination with the ANT ivy:report task I came up with the following solution:

The following is just an example ANT target that demonstrates the use of the actual XSLT:

<target name="generate" depends="resolve">
    <ivy:report todir="${bin.archive.dir}/META-INF" outputpattern="application.xml" graph="false" xslfile="ivy-report-appxml14.xsl"/>
</target>

The part that does all the actual work is the following XSLT definition (ivy-report-appxml14.xsl in the above example):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes"/>

    <xsl:variable name="modules" select="/ivy-report/dependencies/module"/>
    <xsl:variable name="revisions" select="$modules/revision"/>
    <xsl:variable name="artifacts" select="$revisions/artifacts/artifact"/>
    
    <xsl:template name="calling">
        <xsl:param name="org"/>
        <xsl:param name="mod"/>
        <xsl:param name="rev"/>
        <xsl:if test="count($modules/revision/caller[(@organisation=$org and @name=$mod) and @callerrev=$rev]) > 0">
            <module>
               <xsl:for-each select="$modules/revision/caller[(@organisation=$org and @name=$mod) and @callerrev=$rev]">
                 <xsl:call-template name="called">
                   <xsl:with-param name="revision" select=".."/>
                 </xsl:call-template>
               </xsl:for-each>   
            </module>
        </xsl:if>
    </xsl:template>
    
    <xsl:template name="called">
        <xsl:param name="revision"/>
    
        <xsl:param name="module" select="$revision/../@name"/>
        <xsl:param name="rev" select="$revision/@name"/>
        <xsl:param name="type" select="$revision/artifacts/artifact/@type"/>
        <xsl:param name="ext" select="$revision/artifacts/artifact/@ext"/>
        <xsl:param name="artifact" select="concat($module, '-', $rev, '.', $ext)"/>
        
        <xsl:if test="$type='ejb'">
            <ejb>
                <xsl:value-of select="$artifact"/>
            </ejb>
        </xsl:if>
        
        <xsl:if test="$type='war'">
            <web>
                <web-uri>
                    <xsl:value-of select="$artifact"/>
                </web-uri>
            </web>
        </xsl:if>

        <xsl:if test="$type='jar'">
            <web>
                <module>
                    <java><xsl:value-of select="$artifact"/></java>
                </module>
            </web>
        </xsl:if>
    </xsl:template>
    
    <xsl:template match="/ivy-report">
        <application version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd">
            <display-name><xsl:value-of select="info/@module"/></display-name>
            <xsl:call-template name="calling">
                <xsl:with-param name="org" select="info/@organisation"/>
                <xsl:with-param name="mod" select="info/@module"/>
                <xsl:with-param name="rev" select="info/@revision"/>
            </xsl:call-template>
        </application>
    </xsl:template>

</xsl:stylesheet>

It is very much based on the default HTML report generator supplied together with the Ivy distribution. By no means is this a solution that will work in any situation. But with minor tweaks it should be applicable to most EAR projects that define their module dependencies through Ivy.

When run from within the EAR project context it does the following:

  • Iterate over the top-level dependencies of the EAR project (its application modules/wars/ejb-jars)
  • Construct an appropriate module element in the resulting deployment descriptor based on the published artifact type definition in the dependencies ivy.xml

In its current form the XSLT does not take into account the following:

  • EAR deployment descriptor version and resulting document structure
  • WAR module <context-root> element is being omitted
  • No labels