Documenting Validation in XPages
The last thing in a developer's mind is documentation since developers believe that hardly anyone reads it as long as nothing goes wrong or needs to be changed. What works comparable well is the generation of documentation out of code. JavaDoc, JSDoc and LSDoc are examples for such tools. They work well when the code has little external dependencies. When validating form submissions however documenting what field gets validated would be missing. I'm advocating to use validators rather than onSubmit code, since they allow to generate this documentation easily (at least when you wrap your head around XML and XSLT). Since an XPage or a custom control is XML we can use XSLT to generate documentation (how exactly the transformation could run is subject to a future post). You can end with a report like this:
The (not covering all types of validators yet) stylesheet looks like this:
The (not covering all types of validators yet) stylesheet looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:xp="http://www.ibm.com/xsp/core"
exclude-result-prefixes="xd"
version="1.0">
<xd:doc scope="stylesheet">
<xd:desc>
<xd:p><xd:b>Created on: </xd:b> Oct 17, 2011 </xd:p>
<xd:p><xd:b>Author: </xd:b> Stephan H. Wissel </xd:p>
</xd:desc>
</xd:doc>
<xsl:output method="html" indent="yes"/>
<xsl:param name="filename">XPage </xsl:param>
<xsl:template match="/">
<html>
<head>
<title>Validators for <xsl:value-of select="$filename"/></title>
<link rel="stylesheet" href="style.css" type="text/css" media="screen" />
</head>
<body>
<h1>Validators for <xsl:value-of select="$filename"/></h1>
<table>
<thead>
<tr>
<th>Control </th>
<th>Validator </th>
<th>Code </th>
<th>Message </th>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="descendant::*[xp:this.validators]"></xsl:apply-templates>
</tbody>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="xp:this.validators">
<xsl:variable name="rowspan" select="count(child::*)+1"></xsl:variable>
<tr class="fieldname">
<td rowspan="{$rowspan}" class="fieldname"><xsl:value-of select="ancestor::*[1]/@id"/></td>
<td class="fieldtype" colspan="3">
<xsl:value-of select="name(ancestor::*[1])"/> -
<xsl:value-of select="count(child::*)"/> validator(s)
</td>
</tr>
<xsl:apply-templates />
</xsl:template>
<xsl:template match="xp:validateRequired">
<tr class="validator">
<td class="validatortype">Required </td>
<td class="validatorcode"></td>
<td class="validatormessage"><xsl:value-of select="@message"/></td>
</tr>
</xsl:template>
<xsl:template match="xp:validateExpression">
<tr class="validator">
<td class="validatortype">Expression </td>
<td class="validatorcode"><xsl:value-of select="xp:this.expression"/></td>
<td class="validatormessage"><xsl:value-of select="@message"/></td>
</tr>
</xsl:template>
<xsl:template match="xp:validateLength">
<tr class="validator">
<td class="validatortype">Length </td>
<td class="validatorcode">min: <xsl:value-of select="@minimum"/> max: <xsl:value-of select="@maximum"/></td>
<td class="validatormessage"><xsl:value-of select="@message"/></td>
</tr>
</xsl:template>
<!-- Catch validators we don't know exclude types as you add them above-->
<xsl:template match="xp:this.validators/*[name(.) != 'xp:validateLength' and name(.) != 'xp:validateRequired' and name(.) != 'xp:validateExpression']">
<tr class="validator">
<td class="validatortype"><xsl:value-of select="name(.)"/></td>
<td class="validatorcode">please check source code! </td>
<td class="validatormessage"><xsl:value-of select="@message"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
As usual YMMV<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:xp="http://www.ibm.com/xsp/core"
exclude-result-prefixes="xd"
version="1.0">
<xd:doc scope="stylesheet">
<xd:desc>
<xd:p><xd:b>Created on: </xd:b> Oct 17, 2011 </xd:p>
<xd:p><xd:b>Author: </xd:b> Stephan H. Wissel </xd:p>
</xd:desc>
</xd:doc>
<xsl:output method="html" indent="yes"/>
<xsl:param name="filename">XPage </xsl:param>
<xsl:template match="/">
<html>
<head>
<title>Validators for <xsl:value-of select="$filename"/></title>
<link rel="stylesheet" href="style.css" type="text/css" media="screen" />
</head>
<body>
<h1>Validators for <xsl:value-of select="$filename"/></h1>
<table>
<thead>
<tr>
<th>Control </th>
<th>Validator </th>
<th>Code </th>
<th>Message </th>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="descendant::*[xp:this.validators]"></xsl:apply-templates>
</tbody>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="xp:this.validators">
<xsl:variable name="rowspan" select="count(child::*)+1"></xsl:variable>
<tr class="fieldname">
<td rowspan="{$rowspan}" class="fieldname"><xsl:value-of select="ancestor::*[1]/@id"/></td>
<td class="fieldtype" colspan="3">
<xsl:value-of select="name(ancestor::*[1])"/> -
<xsl:value-of select="count(child::*)"/> validator(s)
</td>
</tr>
<xsl:apply-templates />
</xsl:template>
<xsl:template match="xp:validateRequired">
<tr class="validator">
<td class="validatortype">Required </td>
<td class="validatorcode"></td>
<td class="validatormessage"><xsl:value-of select="@message"/></td>
</tr>
</xsl:template>
<xsl:template match="xp:validateExpression">
<tr class="validator">
<td class="validatortype">Expression </td>
<td class="validatorcode"><xsl:value-of select="xp:this.expression"/></td>
<td class="validatormessage"><xsl:value-of select="@message"/></td>
</tr>
</xsl:template>
<xsl:template match="xp:validateLength">
<tr class="validator">
<td class="validatortype">Length </td>
<td class="validatorcode">min: <xsl:value-of select="@minimum"/> max: <xsl:value-of select="@maximum"/></td>
<td class="validatormessage"><xsl:value-of select="@message"/></td>
</tr>
</xsl:template>
<!-- Catch validators we don't know exclude types as you add them above-->
<xsl:template match="xp:this.validators/*[name(.) != 'xp:validateLength' and name(.) != 'xp:validateRequired' and name(.) != 'xp:validateExpression']">
<tr class="validator">
<td class="validatortype"><xsl:value-of select="name(.)"/></td>
<td class="validatorcode">please check source code! </td>
<td class="validatormessage"><xsl:value-of select="@message"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
Posted by Stephan H Wissel on 17 October 2011 | Comments (0) | categories: XPages