Search code examples
jsfxml-parsingtag-handler

Force the XML parser to raise a parse error, if irrelevant tag attributes were to be specified in a tag


I have a basic tag handler for a JSF converter as follows (several things have been omitted for brevity).

<tag>
    <description>
        <![CDATA[
            Converts a string representation to 
            <code>java.math.BigDecimal</code> based on attribute values given.
        ]]>
    </description>
    <tag-name>convertBigDecimal</tag-name>
    <converter><converter-id>bigDecimalConverter</converter-id></converter>

    <attribute>
        <description>
            <![CDATA[
                <a href="https://en.wikipedia.org/wiki/ISO_4217">ISO 4217 currency code</a> such as INR, USD, GBP, NZD etc.
            ]]>
        </description>
        <name>currency</name>
        <type>java.lang.String</type>
    </attribute>

    <attribute>
        <description>
            <![CDATA[
                A boolean value or flag indicating whether to transform 
                this value to percentage or not. The default is false.
            ]]>
        </description>
        <name>percent</name>
        <type>java.lang.Boolean</type>
    </attribute>

    <attribute>
        <description>
            <![CDATA[
                A boolean value or flag indicating whether to use a 
                currency symbol (such as $) or not. The default is true.
            ]]>
        </description>
        <name>useCurrencySymbol</name>
        <type>java.lang.Boolean</type>
    </attribute>

    <!-- Other attributes. -->
</tag>

It has several attributes and it is targeted to convert a string representation to its equivalent java.math.BigDecimal value and a java.math.BigDecimal to various display formats like currency with or without a currency symbol, percentage, numbers with grouping, number of decimal places in fractional numbers etc.

Naturally, percentage and currency cannot be used together in the example given. So, the following is perfectly valid.

<my:convertBigDecimal currency="#{currencyCode}" groupingUsed="true" locale="#{locale}"/>

The following would however be invalid and is expected to raise a parse error, if attempted.

<my:convertBigDecimal percent="true"
                      currency="#{currencyCode}"
                      useCurrencySymbol="false"
                      groupingUsed="true"
                      locale="#{locale}"/>

If for example, the percent attribute were to be attempted along with any other attributes associated with currencies like currency, useCurrencySymbol, then it is supposed that the XML parser should issue a parse error preventing the XML document itself from being parsed.

Would it be possible somehow to force the parser to issue a parse error, if irrelevant attributes were to be attempted to be specified together with the given tag so that several conditional tests in the converter can be omitted and users or application developers using the converter can be warned against using irrelevant attributes in the tag too early?


Solution

  • Unfortunately not via XML configuration in .taglib.xml file. It's only possible via a real tag handler class registered via <converter><handler-class>.

    <converter>
        <converter-id>bigDecimalConverter</converter-id>
        <handler-class>com.example.BigDecimalConverterHandler</handler-class>
    </converter>
    

    public class BigDecimalConverterHandler extends ConverterHandler {
    
        public BigDecimalConverterHandler(ConverterConfig config) {
            super(config);
    
            if (getAttribute("percent") != null && getAttribute("currency") != null) {
                throw new IllegalArgumentException("Hey there, it does not make sense to specify both 'percent' and 'currency' attributes.");
            }
        }
    
    }