4.5.10. apply

The apply method provides the actual implementation of the checks. Following listing shows the implementation of the check_length check:
public String apply(String content, HTMLRuleContext ctx)
{
    String lang = ctx.getUILocale().getLanguage();
    String result = null;
   
    if (ctx.isEnabled(CHECK_LENGTH)) {
        if (content.length() > maxLength) {
            ctx.log(CHECK_LENGTH,
                    label(lang, "length_exceeded", maxLength));
        }
    }
   
    // ... implementation of further checks ...

    return result;
}
Before executing a check, it has to be assured that the check is enabled. Otherwise the check has to be skipped. Whether a check is enabled or disabled is returned by the isEnabled method of the org.docma.plugin.rules.HTMLRuleContext instance. The content that needs to be checked is passed in the content argument. If the check is enabled, the implementation just compares the length of the content with the configured maxLength value. If the content length exceeds the configured maximum length, a log message is written.
The log message is retrieved as localized string by calling the label method that we have already used before (see Section 4.5.1, “getShortInfo”). However, this time the user interface language needs to be retrieved through the getUILocale method of the ctx parameter. Note that you do not have to provide the severity of the log message, because the log message is automatically written as "Error", "Warning" or "Info", depending on the log level that is configured for the checks (or the default level that is defined by the getDefaultLogLevel method).
The result variable in the listing above is not used yet. Currently it stores the return value null. As long as a rule does not support auto-correction, the apply method has to return null. However, if a rule corrects the content, then the modified content needs to be returned instead of null. This is shown in the following implementation of the check_empty_span check.
The implementation of the check_empty_span check shall allow auto-correction. That means, if auto-correction is enabled for this check, then empty spans shall be removed from the content. Otherwise empty spans shall just be reported in the log. In the following code this is simply realized by searching and removing the substring "<span></span>". Of course, a real world implementation would have to do XML processing to handle all possible cases of empty spans. However, this example shall just show the principles of implementing a check that supports auto-correction.
Following the code of the apply method already described above for the check_length check, but this time including the implementation of the check_empty_span checks:
public String apply(String content, HTMLRuleContext ctx)
{
    String lang = ctx.getUILocale().getLanguage();
    String result = null;
   
    if (ctx.isEnabled(CHECK_LENGTH)) {
        if (content.length() > maxLength) {
            ctx.log(CHECK_LENGTH,
                    label(lang, "length_exceeded", maxLength));
        }
    }
   
    if (ctx.isEnabled(CHECK_EMPTY_SPAN)) {
        final String EMPTY_SPAN = "<span></span>";
        boolean updated = false;
        int pos = 0;
        while ((pos = content.indexOf(EMPTY_SPAN, pos)) >= 0) {
            if (ctx.isAutoCorrect(CHECK_EMPTY_SPAN)) {
                content = content.substring(0, pos) +
                          content.substring(pos + EMPTY_SPAN.length());
                ctx.logInfo(CHECK_EMPTY_SPAN, pos,
                            label(lang, "empty_span_removed"));
                updated = true;
            } else {
                ctx.log(CHECK_EMPTY_SPAN, pos,
                        label(lang, "empty_span_exists"));
                pos += EMPTY_SPAN.length();
            }
        }
        if (updated) {  // empty span has been removed
            result = content;  
        }
    }
   
    // return modified content, or null if content is unchanged
    return result;
}
First, it has to be determined whether the check is enabled at all, by calling ctx.isEnabled(CHECK_EMPTY_SPAN). If the check is enabled, then the next occurrence of "<span></span>" is searched. If an empty span is found, then the isAutoCorrect method of the HTMLRuleContext object is called to determine whether auto-correction is enabled. If auto-correction is enabled, then the substring "<span></span>" is removed from the content string. On the other side, if auto-correction is disabled, then just a log message is written by invoking the log message of the HTMLRuleContext object.
Note that the position pos of the empty span is passed as argument to the log method. This allows the logger to include an extract of the XHTML source at the given position into the log message. This may be helpful for the end-user to locate the error position in the content. The log message itself is retrieved through the label method that we have already used before (see Section 4.5.1, “getShortInfo”).
You might wonder, why in case of auto-correction, a log message is written by invoking the logInfo method instead of log. The logInfo method writes a log message with severity "Info", no matter which log level is defined for the given check. This is important, because after having removed the empty span, no error or warning should be logged, as the content has automatically been corrected (the error/warning condition no longer applies).