終了タグをレンダリングする代わりに、html5 void 要素を短縮する独自の MarkupModel で MarkupWriterFactory サービスをオーバーライドできます。
public class Html5MarkupModel extends AbstractMarkupModel {
private static final Set<String> VOID_ELEMENTS = new HashSet<String>(Arrays.asList(
"area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"
));
public Html5MarkupModel(boolean useApostropheForAttributes) {
super(useApostropheForAttributes);
}
public EndTagStyle getEndTagStyle(String element) {
return VOID_ELEMENTS.contains(element) ? EndTagStyle.ABBREVIATE : EndTagStyle.REQUIRE;
}
public boolean isXML() {
return false;
}
}
public class Html5MarkupWriterFactory implements MarkupWriterFactory {
private final PageContentTypeAnalyzer analyzer;
private final RequestPageCache cache;
private final MarkupModel htmlModel = new Html5MarkupModel(false);
private final MarkupModel htmlPartialModel = new Html5MarkupModel(true);
private final MarkupModel xmlModel = new XMLMarkupModel();
private final MarkupModel xmlPartialModel = new XMLMarkupModel(true);
public Html5MarkupWriterFactory(PageContentTypeAnalyzer analyzer, RequestPageCache cache) {
this.analyzer = analyzer;
this.cache = cache;
}
public MarkupWriter newMarkupWriter(ContentType contentType) {
return newMarkupWriter(contentType, false);
}
public MarkupWriter newPartialMarkupWriter(ContentType contentType) {
return newMarkupWriter(contentType, true);
}
public MarkupWriter newMarkupWriter(String pageName) {
return newMarkupWriter(analyzer.findContentType(cache.get(pageName)));
}
private MarkupWriter newMarkupWriter(ContentType contentType, boolean partial) {
boolean isHTML = contentType.getMimeType().equalsIgnoreCase("text/html");
MarkupModel model = partial
? (isHTML ? htmlPartialModel : xmlPartialModel)
: (isHTML ? htmlModel : xmlModel);
// The charset parameter sets the encoding attribute of the XML declaration, if
// not null and if using the XML model.
return new MarkupWriterImpl(model, contentType.getCharset());
}
}
そしてサービスのオーバーライド貢献:
@Contribute(ServiceOverride.class)
public void contributeServiceOverrides(MappedConfiguration<Class, Object> configuration,
ObjectLocator objectLocator) {
// use proxy instead of real service instance
// to prevent recursion on initialization cycle
configuration.add(MarkupWriterFactory.class,
objectLocator.proxy(MarkupWriterFactory.class, Html5MarkupWriterFactory.class));
}