package org.springframework.roo.support.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.tuple.Pair;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Helper util class to allow more convenient handling of web.xml file in Web
* projects.
*
* @author Stefan Schmidt
* @since 1.1
*/
public final class WebXmlUtils {
/**
* Enum to define dispatcher
*
* @author Stefan Schmidt
* @since 1.1.1
*/
public static enum Dispatcher {
ERROR, FORWARD, INCLUDE, REQUEST;
}
/**
* Enum to define filter position
*
* @author Stefan Schmidt
* @since 1.1
*/
public static enum FilterPosition {
AFTER, BEFORE, BETWEEN, FIRST, LAST;
}
/**
* Convenience class for passing a web-resource-collection element's details
*
* @since 1.1.1
*/
public static class WebResourceCollection {
private final String description;
private final List<String> httpMethods;
private final List<String> urlPatterns;
private final String webResourceName;
public WebResourceCollection(final String webResourceName,
final String description, final List<String> urlPatterns,
final List<String> httpMethods) {
this.webResourceName = webResourceName;
this.description = description;
this.urlPatterns = urlPatterns;
this.httpMethods = httpMethods;
}
public String getDescription() {
return description;
}
public List<String> getHttpMethods() {
return httpMethods;
}
public List<String> getUrlPatterns() {
return urlPatterns;
}
public String getWebResourceName() {
return webResourceName;
}
}
/**
* Value object that holds init-param style information
*
* @author Stefan Schmidt
* @since 1.1
*/
public static class WebXmlParam extends Pair<String, String> {
private static final long serialVersionUID = -1134907409024055399L;
private final String name;
private final String value;
public WebXmlParam(final String name, final String value) {
this.name = name;
this.value = value;
}
@Override
public String getLeft() {
return name;
}
@Override
public String getRight() {
return value;
}
public String getName() {
return getLeft();
}
public String setValue(final String value) {
throw new UnsupportedOperationException();
}
}
private static final String WEB_APP_XPATH = "/web-app/";
private static final String WHITESPACE = "[ \t\r\n]";
private static void addCommentBefore(final Element element,
final String comment, final Document document) {
if (null == XmlUtils.findNode("//comment()[.=' " + comment + " ']",
document.getDocumentElement())) {
document.getDocumentElement().insertBefore(
document.createComment(" " + comment + " "), element);
addLineBreakBefore(element, document);
}
}
/**
* Add a context param to the web.xml document
*
* @param contextParam (required)
* @param document the web.xml document (required)
* @param comment (optional)
*/
public static void addContextParam(final WebXmlParam contextParam,
final Document document, final String comment) {
Validate.notNull(document, "Web XML document required");
Validate.notNull(contextParam, "Context param required");
Element contextParamElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ "context-param[param-name = '" + contextParam.getName()
+ "']", document.getDocumentElement());
if (contextParamElement == null) {
contextParamElement = new XmlElementBuilder("context-param",
document).addChild(
new XmlElementBuilder("param-name", document).setText(
contextParam.getName()).build()).build();
insertBetween(contextParamElement, "description[last()]", "filter",
document);
if (StringUtils.isNotBlank(comment)) {
addCommentBefore(contextParamElement, comment, document);
}
}
appendChildIfNotPresent(contextParamElement, new XmlElementBuilder(
"param-value", document).setText(contextParam.getValue())
.build());
}
/**
* Add error code to web.xml document
*
* @param errorCode (required)
* @param location (required)
* @param document (required)
* @param comment (optional)
*/
public static void addErrorCode(final Integer errorCode,
final String location, final Document document, final String comment) {
Validate.notNull(document, "Web XML document required");
Validate.notNull(errorCode, "Error code required");
Validate.notBlank(location, "Location required");
Element errorPageElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ "error-page[error-code = '" + errorCode.toString() + "']",
document.getDocumentElement());
if (errorPageElement == null) {
errorPageElement = new XmlElementBuilder("error-page", document)
.addChild(
new XmlElementBuilder("error-code", document)
.setText(errorCode.toString()).build())
.build();
insertBetween(errorPageElement, "welcome-file-list[last()]",
"the-end", document);
if (StringUtils.isNotBlank(comment)) {
addCommentBefore(errorPageElement, comment, document);
}
}
appendChildIfNotPresent(errorPageElement, new XmlElementBuilder(
"location", document).setText(location).build());
}
/**
* Add exception type to web.xml document
*
* @param exceptionType fully qualified exception type name (required)
* @param location (required)
* @param document (required)
* @param comment (optional)
*/
public static void addExceptionType(final String exceptionType,
final String location, final Document document, final String comment) {
Validate.notNull(document, "Web XML document required");
Validate.notBlank(exceptionType,
"Fully qualified exception type name required");
Validate.notBlank(location, "location required");
Element errorPageElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ "error-page[exception-type = '" + exceptionType + "']",
document.getDocumentElement());
if (errorPageElement == null) {
errorPageElement = new XmlElementBuilder("error-page", document)
.addChild(
new XmlElementBuilder("exception-type", document)
.setText(exceptionType).build()).build();
insertBetween(errorPageElement, "welcome-file-list[last()]",
"the-end", document);
if (StringUtils.isNotBlank(comment)) {
addCommentBefore(errorPageElement, comment, document);
}
}
appendChildIfNotPresent(errorPageElement, new XmlElementBuilder(
"location", document).setText(location).build());
}
/**
* Add a new filter definition to web.xml document. The filter will be added
* AFTER (FilterPosition.LAST) all existing filters.
*
* @param filterName (required)
* @param filterClass the fully qualified name of the filter type (required)
* @param urlPattern (required)
* @param document the web.xml document (required)
* @param comment (optional)
* @param initParams a vararg of initial parameters (optional)
*/
public static void addFilter(final String filterName,
final String filterClass, final String urlPattern,
final Document document, final String comment,
final WebXmlParam... initParams) {
addFilterAtPosition(FilterPosition.LAST, null, null, filterName,
filterClass, urlPattern, document, comment, initParams);
}
/**
* Add a new filter definition to web.xml document. The filter will be added
* at the FilterPosition specified.
*
* @param filterPosition Filter position (required)
* @param beforeFilterName (optional for filter position FIRST and LAST,
* required for BEFORE and AFTER)
* @param filterName (required)
* @param filterClass the fully qualified name of the filter type (required)
* @param urlPattern (required)
* @param document the web.xml document (required)
* @param comment (optional)
* @param initParams (optional)
* @param dispatchers (optional)
*/
public static void addFilterAtPosition(final FilterPosition filterPosition,
final String afterFilterName, final String beforeFilterName,
final String filterName, final String filterClass,
final String urlPattern, final Document document,
final String comment, List<WebXmlParam> initParams,
final List<Dispatcher> dispatchers) {
Validate.notNull(document, "Web XML document required");
Validate.notBlank(filterName, "Filter name required");
Validate.notBlank(filterClass, "Filter class required");
Validate.notNull(urlPattern, "Filter URL mapping pattern required");
if (initParams == null) {
initParams = new ArrayList<WebXmlUtils.WebXmlParam>();
}
// Creating filter
Element filterElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ "filter[filter-name = '" + filterName + "']",
document.getDocumentElement());
if (filterElement == null) {
filterElement = new XmlElementBuilder("filter", document).addChild(
new XmlElementBuilder("filter-name", document).setText(
filterName).build()).build();
if (filterPosition.equals(FilterPosition.FIRST)) {
insertBetween(filterElement, "context-param", "filter",
document);
}
else if (filterPosition.equals(FilterPosition.BEFORE)) {
Validate.notBlank(beforeFilterName,
"The filter position filter name is required when using FilterPosition.BEFORE");
insertBefore(filterElement, "filter[filter-name = '"
+ beforeFilterName + "']", document);
}
else if (filterPosition.equals(FilterPosition.AFTER)) {
Validate.notBlank(afterFilterName,
"The filter position filter name is required when using FilterPosition.AFTER");
insertAfter(filterElement, "filter[filter-name = '"
+ afterFilterName + "']", document);
}
else if (filterPosition.equals(FilterPosition.BETWEEN)) {
Validate.notBlank(beforeFilterName,
"The 'before' filter name is required when using FilterPosition.BETWEEN");
Validate.notBlank(afterFilterName,
"The 'after' filter name is required when using FilterPosition.BETWEEN");
insertBetween(filterElement, "filter[filter-name = '"
+ afterFilterName + "']", "filter[filter-name = '"
+ beforeFilterName + "']", document);
}
else {
insertBetween(filterElement, "context-param[last()]",
"filter-mapping", document);
}
if (StringUtils.isNotBlank(comment)) {
addCommentBefore(filterElement, comment, document);
}
}
appendChildIfNotPresent(filterElement, new XmlElementBuilder(
"filter-class", document).setText(filterClass).build());
for (final WebXmlParam initParam : initParams) {
appendChildIfNotPresent(
filterElement,
new XmlElementBuilder("init-param", document)
.addChild(
new XmlElementBuilder("param-name",
document).setText(
initParam.getName()).build())
.addChild(
new XmlElementBuilder("param-value",
document).setText(
initParam.getValue()).build())
.build());
}
// Creating filter mapping
Element filterMappingElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ "filter-mapping[filter-name = '" + filterName + "']",
document.getDocumentElement());
if (filterMappingElement == null) {
filterMappingElement = new XmlElementBuilder("filter-mapping",
document).addChild(
new XmlElementBuilder("filter-name", document).setText(
filterName).build()).build();
if (filterPosition.equals(FilterPosition.FIRST)) {
insertBetween(filterMappingElement, "filter", "filter-mapping",
document);
}
else if (filterPosition.equals(FilterPosition.BEFORE)) {
insertBefore(filterMappingElement,
"filter-mapping[filter-name = '" + beforeFilterName
+ "']", document);
}
else if (filterPosition.equals(FilterPosition.AFTER)) {
insertAfter(filterMappingElement,
"filter-mapping[filter-name = '" + beforeFilterName
+ "']", document);
}
else if (filterPosition.equals(FilterPosition.BETWEEN)) {
insertBetween(filterMappingElement,
"filter-mapping[filter-name = '" + afterFilterName
+ "']", "filter-mapping[filter-name = '"
+ beforeFilterName + "']", document);
}
else {
insertBetween(filterMappingElement, "filter-mapping[last()]",
"listener", document);
}
}
appendChildIfNotPresent(filterMappingElement, new XmlElementBuilder(
"url-pattern", document).setText(urlPattern).build());
for (final Dispatcher dispatcher : dispatchers) {
appendChildIfNotPresent(
filterMappingElement,
new XmlElementBuilder("dispatcher", document).setText(
dispatcher.name()).build());
}
}
/**
* Add a new filter definition to web.xml document. The filter will be added
* at the FilterPosition specified.
*
* @param filterPosition Filter position (required)
* @param beforeFilterName (optional for filter position FIRST and LAST,
* required for BEFORE and AFTER)
* @param filterName (required)
* @param filterClass the fully qualified name of the filter type (required)
* @param urlPattern (required)
* @param document the web.xml document (required)
* @param comment (optional)
* @param initParams (optional)
*/
public static void addFilterAtPosition(final FilterPosition filterPosition,
final String afterFilterName, final String beforeFilterName,
final String filterName, final String filterClass,
final String urlPattern, final Document document,
final String comment, final WebXmlParam... initParams) {
addFilterAtPosition(
filterPosition,
afterFilterName,
beforeFilterName,
filterName,
filterClass,
urlPattern,
document,
comment,
initParams == null ? new ArrayList<WebXmlParam>() : Arrays
.asList(initParams), new ArrayList<Dispatcher>());
}
private static void addLineBreakBefore(final Element element,
final Document document) {
document.getDocumentElement().insertBefore(
document.createTextNode("\n "), element);
}
/**
* Add listener element to web.xml document
*
* @param className the fully qualified name of the listener type (required)
* @param document (required)
* @param comment (optional)
*/
public static void addListener(final String className,
final Document document, final String comment) {
Validate.notNull(document, "Web XML document required");
Validate.notBlank(className, "Class name required");
Element listenerElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ "listener[listener-class = '" + className + "']",
document.getDocumentElement());
if (listenerElement == null) {
listenerElement = new XmlElementBuilder("listener", document)
.addChild(
new XmlElementBuilder("listener-class", document)
.setText(className).build()).build();
insertBetween(listenerElement, "filter-mapping[last()]", "servlet",
document);
if (StringUtils.isNotBlank(comment)) {
addCommentBefore(listenerElement, comment, document);
}
}
}
/**
* Add a security constraint to a web.xml document
*
* @param displayName (optional)
* @param webResourceCollections (required)
* @param roleNames (optional)
* @param transportGuarantee (optional)
* @param document (required)
* @param comment (optional)
*/
public static void addSecurityConstraint(final String displayName,
final List<WebResourceCollection> webResourceCollections,
final List<String> roleNames, final String transportGuarantee,
final Document document, final String comment) {
Validate.notNull(document, "Web XML document required");
Validate.isTrue(
!CollectionUtils.isEmpty(webResourceCollections),
"A security-constraint element must contain at least one web-resource-collection");
Element securityConstraintElement = XmlUtils.findFirstElement(
"security-constraint", document.getDocumentElement());
if (securityConstraintElement == null) {
securityConstraintElement = document
.createElement("security-constraint");
insertAfter(securityConstraintElement, "session-config[last()]",
document);
if (StringUtils.isNotBlank(comment)) {
addCommentBefore(securityConstraintElement, comment, document);
}
}
if (StringUtils.isNotBlank(displayName)) {
appendChildIfNotPresent(
securityConstraintElement,
new XmlElementBuilder("display-name", document).setText(
displayName).build());
}
for (final WebResourceCollection webResourceCollection : webResourceCollections) {
final XmlElementBuilder webResourceCollectionBuilder = new XmlElementBuilder(
"web-resource-collection", document);
Validate.notBlank(webResourceCollection.getWebResourceName(),
"web-resource-name is required");
webResourceCollectionBuilder.addChild(new XmlElementBuilder(
"web-resource-name", document).setText(
webResourceCollection.getWebResourceName()).build());
if (StringUtils.isNotBlank(webResourceCollection.getDescription())) {
webResourceCollectionBuilder.addChild(new XmlElementBuilder(
"description", document).setText(
webResourceCollection.getWebResourceName()).build());
}
for (final String urlPattern : webResourceCollection
.getUrlPatterns()) {
if (StringUtils.isNotBlank(urlPattern)) {
webResourceCollectionBuilder
.addChild(new XmlElementBuilder("url-pattern",
document).setText(urlPattern).build());
}
}
for (final String httpMethod : webResourceCollection
.getHttpMethods()) {
if (StringUtils.isNotBlank(httpMethod)) {
webResourceCollectionBuilder
.addChild(new XmlElementBuilder("http-method",
document).setText(httpMethod).build());
}
}
appendChildIfNotPresent(securityConstraintElement,
webResourceCollectionBuilder.build());
}
if (roleNames != null && roleNames.size() > 0) {
final XmlElementBuilder authConstraintBuilder = new XmlElementBuilder(
"auth-constraint", document);
for (final String roleName : roleNames) {
if (StringUtils.isNotBlank(roleName)) {
authConstraintBuilder.addChild(new XmlElementBuilder(
"role-name", document).setText(roleName).build());
}
}
appendChildIfNotPresent(securityConstraintElement,
authConstraintBuilder.build());
}
if (StringUtils.isNotBlank(transportGuarantee)) {
final XmlElementBuilder userDataConstraintBuilder = new XmlElementBuilder(
"user-data-constraint", document);
userDataConstraintBuilder.addChild(new XmlElementBuilder(
"transport-guarantee", document)
.setText(transportGuarantee).build());
appendChildIfNotPresent(securityConstraintElement,
userDataConstraintBuilder.build());
}
}
/**
* Add servlet element to the web.xml document
*
* @param servletName (required)
* @param className the fully qualified name of the servlet type (required)
* @param urlPattern this can be set to null in which case the servletName
* will be used for mapping (optional)
* @param loadOnStartup (optional)
* @param document (required)
* @param comment (optional)
* @param initParams (optional)
*/
public static void addServlet(final String servletName,
final String className, final String urlPattern,
final Integer loadOnStartup, final Document document,
final String comment, final WebXmlParam... initParams) {
Validate.notNull(document, "Web XML document required");
Validate.notBlank(servletName, "Servlet name required");
Validate.notBlank(className, "Fully qualified class name required");
// Create servlet
Element servletElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ "servlet[servlet-name = '" + servletName + "']",
document.getDocumentElement());
if (servletElement == null) {
servletElement = new XmlElementBuilder("servlet", document)
.addChild(
new XmlElementBuilder("servlet-name", document)
.setText(servletName).build()).build();
insertBetween(servletElement, "listener[last()]",
"servlet-mapping", document);
if (comment != null && comment.length() > 0) {
addCommentBefore(servletElement, comment, document);
}
}
appendChildIfNotPresent(servletElement, new XmlElementBuilder(
"servlet-class", document).setText(className).build());
for (final WebXmlParam initParam : initParams) {
appendChildIfNotPresent(
servletElement,
new XmlElementBuilder("init-param", document)
.addChild(
new XmlElementBuilder("param-name",
document).setText(
initParam.getName()).build())
.addChild(
new XmlElementBuilder("param-value",
document).setText(
initParam.getValue()).build())
.build());
}
if (loadOnStartup != null) {
appendChildIfNotPresent(
servletElement,
new XmlElementBuilder("load-on-startup", document).setText(
loadOnStartup.toString()).build());
}
// Create servlet mapping
Element servletMappingElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ "servlet-mapping[servlet-name = '" + servletName + "']",
document.getDocumentElement());
if (servletMappingElement == null) {
servletMappingElement = new XmlElementBuilder("servlet-mapping",
document).addChild(
new XmlElementBuilder("servlet-name", document).setText(
servletName).build()).build();
insertBetween(servletMappingElement, "servlet[last()]",
"session-config", document);
}
if (StringUtils.isNotBlank(urlPattern)) {
appendChildIfNotPresent(
servletMappingElement,
new XmlElementBuilder("url-pattern", document).setText(
urlPattern).build());
}
else {
appendChildIfNotPresent(
servletMappingElement,
new XmlElementBuilder("servlet-name", document).setText(
servletName).build());
}
}
/**
* Add a welcome file definition to web.xml document
*
* @param path (required)
* @param document (required)
* @param comment (optional)
*/
public static void addWelcomeFile(final String path,
final Document document, final String comment) {
Validate.notNull(document, "Web XML document required");
Validate.notBlank("Path required");
Element welcomeFileElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ "welcome-file-list", document.getDocumentElement());
if (welcomeFileElement == null) {
welcomeFileElement = document.createElement("welcome-file-list");
insertBetween(welcomeFileElement, "session-config[last()]",
"error-page", document);
if (StringUtils.isNotBlank(comment)) {
addCommentBefore(welcomeFileElement, comment, document);
}
}
appendChildIfNotPresent(welcomeFileElement, new XmlElementBuilder(
"welcome-file", document).setText(path).build());
}
/**
* Adds the given child to the given parent if it's not already there
*
* @param parent the parent to which to add a child (required)
* @param child the child to add if not present (required)
*/
private static void appendChildIfNotPresent(final Node parent,
final Element child) {
final NodeList existingChildren = parent.getChildNodes();
for (int i = 0; i < existingChildren.getLength(); i++) {
final Node existingChild = existingChildren.item(i);
if (existingChild instanceof Element) {
// Attempt matching of possibly nested structures by using of
// 'getTextContent' as 'isEqualNode' does not match due to line
// returns, etc
// Note, this does not work if child nodes are appearing in a
// different order than expected
if (existingChild.getNodeName().equals(child.getNodeName())
&& existingChild
.getTextContent()
.replaceAll(WHITESPACE, "")
.trim()
.equals(child.getTextContent().replaceAll(
WHITESPACE, ""))) {
// If we found a match, there is no need to append the child
// element
return;
}
}
}
parent.appendChild(child);
}
private static void insertAfter(final Element element,
final String afterElementName, final Document document) {
final Element afterElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ afterElementName, document.getDocumentElement());
if (afterElement != null && afterElement.getNextSibling() != null
&& afterElement.getNextSibling() instanceof Element) {
document.getDocumentElement().insertBefore(element,
afterElement.getNextSibling());
addLineBreakBefore(element, document);
addLineBreakBefore(element, document);
return;
}
document.getDocumentElement().appendChild(element);
addLineBreakBefore(element, document);
addLineBreakBefore(element, document);
}
private static void insertBefore(final Element element,
final String beforeElementName, final Document document) {
final Element beforeElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ beforeElementName, document.getDocumentElement());
if (beforeElement != null) {
document.getDocumentElement().insertBefore(element, beforeElement);
addLineBreakBefore(element, document);
addLineBreakBefore(element, document);
return;
}
document.getDocumentElement().appendChild(element);
addLineBreakBefore(element, document);
addLineBreakBefore(element, document);
}
private static void insertBetween(final Element element,
final String afterElementName, final String beforeElementName,
final Document document) {
final Element beforeElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ beforeElementName, document.getDocumentElement());
if (beforeElement != null) {
document.getDocumentElement().insertBefore(element, beforeElement);
addLineBreakBefore(element, document);
addLineBreakBefore(element, document);
return;
}
final Element afterElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ afterElementName, document.getDocumentElement());
if (afterElement != null && afterElement.getNextSibling() != null
&& afterElement.getNextSibling() instanceof Element) {
document.getDocumentElement().insertBefore(element,
afterElement.getNextSibling());
addLineBreakBefore(element, document);
addLineBreakBefore(element, document);
return;
}
document.getDocumentElement().appendChild(element);
addLineBreakBefore(element, document);
addLineBreakBefore(element, document);
}
/**
* Set the description element in the web.xml document.
*
* @param description (required)
* @param document the web.xml document (required)
* @param comment (optional)
*/
public static void setDescription(final String description,
final Document document, final String comment) {
Validate.notNull(document, "Web XML document required");
Validate.notBlank(description, "Description required");
Element descriptionElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ "description", document.getDocumentElement());
if (descriptionElement == null) {
descriptionElement = document.createElement("description");
insertBetween(descriptionElement, "display-name[last()]",
"context-param", document);
if (StringUtils.isNotBlank(comment)) {
addCommentBefore(descriptionElement, comment, document);
}
}
descriptionElement.setTextContent(description);
}
/**
* Set the display-name element in the web.xml document.
*
* @param displayName (required)
* @param document the web.xml document (required)
* @param comment (optional)
*/
public static void setDisplayName(final String displayName,
final Document document, final String comment) {
Validate.notBlank(displayName, "display name required");
Validate.notNull(document, "Web XML document required");
Element displayNameElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ "display-name", document.getDocumentElement());
if (displayNameElement == null) {
displayNameElement = document.createElement("display-name");
insertBetween(displayNameElement, "the-start", "description",
document);
if (StringUtils.isNotBlank(comment)) {
addCommentBefore(displayNameElement, comment, document);
}
}
displayNameElement.setTextContent(displayName);
}
/**
* Set session timeout in web.xml document
*
* @param timeout
* @param document (required)
* @param comment (optional)
*/
public static void setSessionTimeout(final int timeout,
final Document document, final String comment) {
Validate.notNull(document, "Web XML document required");
Validate.notNull(timeout, "Timeout required");
Element sessionConfigElement = XmlUtils.findFirstElement(WEB_APP_XPATH
+ "session-config", document.getDocumentElement());
if (sessionConfigElement == null) {
sessionConfigElement = document.createElement("session-config");
insertBetween(sessionConfigElement, "servlet-mapping[last()]",
"welcome-file-list", document);
if (StringUtils.isNotBlank(comment)) {
addCommentBefore(sessionConfigElement, comment, document);
}
}
appendChildIfNotPresent(sessionConfigElement, new XmlElementBuilder(
"session-timeout", document).setText(String.valueOf(timeout))
.build());
}
/**
* Constructor is private to prevent instantiation
*/
private WebXmlUtils() {
}
}