4.5.11. The complete example

Following the complete source of the Java class myexample.MyHTMLRule:
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 
98 
99 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 
115 
116 
117 
118 
119 
120 
package myexample;
 
import org.docma.plugin.LogLevel;
import org.docma.plugin.PluginUtil;
import org.docma.plugin.rules.HTMLRule;
import org.docma.plugin.rules.HTMLRuleConfig;
import org.docma.plugin.rules.HTMLRuleContext;
 
public class MyHTMLRule implements HTMLRule
{
private static final String CHECK_LENGTH = "check_length";
private static final String CHECK_EMPTY_SPAN = "check_empty_span";
private int maxLength = Integer.MAX_VALUE;
 
@Override
public String getShortInfo(String languageCode)
{
return label(languageCode, "shortInfo");
}
 
@Override
public String getLongInfo(String languageCode)
{
return label(languageCode, "longInfo");
}
 
@Override
public String[] getCheckIds()
{
return new String[] { CHECK_LENGTH, CHECK_EMPTY_SPAN };
}
 
@Override
public String getCheckTitle(String checkId, String languageCode)
{
return label(languageCode, checkId + ".title");
}
 
@Override
public boolean supportsAutoCorrection(String checkId)
{
return checkId.equals(CHECK_EMPTY_SPAN);
}
 
@Override
public LogLevel getDefaultLogLevel(String checkId)
{
return checkId.equals(CHECK_LENGTH) ? LogLevel.WARNING
: LogLevel.ERROR;
}
 
@Override
public void configure(HTMLRuleConfig conf)
{
try {
String a = conf.getArguments()[0];
if (a.toLowerCase().startsWith("maxlength")) {
maxLength =
Integer.parseInt(a.substring(a.indexOf('=') + 1));
return;
}
} catch (Exception ex) {} // no argument or invalid number
maxLength = Integer.MAX_VALUE; // no or invalid argument
}
 
@Override
public void startBatch(HTMLRuleContext ctx)
{
}
 
@Override
public void finishBatch(HTMLRuleContext ctx)
{
}
 
@Override
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"));
}
}
if (updated) { // empty span has been removed
result = content;
}
}
// return modified content, or null if content is unchanged
return result;
}
 
private String label(String lang, String msg, Object... args)
{
return PluginUtil.getResourceString(this.getClass(), lang,
msg, args);
}
}

Listing 4.5.1. MyHTMLRule.java

As already described, the label method in this example loads localized strings from a XML file named MyHTMLRule_en.xml. Following a complete example of the XML file:
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="shortInfo">Checks the length and empty spans.</entry>
<entry key="check_length.title">Checks the content length.</entry>
<entry key="check_empty_span.title">Checks empty spans.</entry>
<entry key="length_exceeded">Content exceeds {0} characters.</entry>
<entry key="empty_span_removed">Removed empty span.</entry>
<entry key="empty_span_exists">Content contains empty span.</entry>
<entry key="longInfo"><![CDATA[
<p>This class provides following checks:</p>
<ul>
<li><a href="#check_length">check_length</a></li>
<li><a href="#check_empty_span">check_empty_span</a></li>
</ul>
<a name="check_length" />
<strong>check_length</strong>
<div style="margin-left:16pt;">
<p>
<u>Arguments:</u>
<dl>
<dt><b><tt>maxlength=[<i>INTEGER</i>|off]</tt></b></dt>
<dd>The maximum content length.</dd>
</dl>
</p>
<p>
<u>Description:</u><br/>
Writes a log message if the content length exceeds
<tt>maxlength</tt>.
</p>
</div>
<a name="check_empty_span" />
<strong>check_empty_span</strong>
<div style="margin-left:16pt;">
<p>
<u>Arguments:</u> <em>none</em>
</p>
<p>
<u>Description:</u><br/>
Creates a log message if the content contains empty spans.
If auto-correction is enabled, removes empty spans.
</p>
</div>
]]>
</entry>
</properties>

Listing 4.5.2. MyHTMLRule_en.xml

Note that the value of the longInfo property is given in a CDATA section. This avoids having to write the < and > characters as character entities (&lt; and &gt;).