| // |
| // ======================================================================== |
| // Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. |
| // ------------------------------------------------------------------------ |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| // |
| |
| |
| package org.eclipse.jetty.quickstart; |
| |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.net.URL; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.EventListener; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.servlet.DispatcherType; |
| import javax.servlet.MultipartConfigElement; |
| import javax.servlet.ServletContext; |
| import javax.servlet.SessionCookieConfig; |
| import javax.servlet.SessionTrackingMode; |
| import javax.servlet.descriptor.JspPropertyGroupDescriptor; |
| import javax.servlet.descriptor.TaglibDescriptor; |
| |
| import org.eclipse.jetty.annotations.AnnotationConfiguration; |
| import org.eclipse.jetty.http.MimeTypes; |
| import org.eclipse.jetty.plus.annotation.LifeCycleCallback; |
| import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection; |
| import org.eclipse.jetty.security.ConstraintAware; |
| import org.eclipse.jetty.security.ConstraintMapping; |
| import org.eclipse.jetty.security.SecurityHandler; |
| import org.eclipse.jetty.security.authentication.FormAuthenticator; |
| import org.eclipse.jetty.servlet.ErrorPageErrorHandler; |
| import org.eclipse.jetty.servlet.FilterHolder; |
| import org.eclipse.jetty.servlet.FilterMapping; |
| import org.eclipse.jetty.servlet.ServletContextHandler.JspConfig; |
| import org.eclipse.jetty.servlet.ServletHandler; |
| import org.eclipse.jetty.servlet.ServletHolder; |
| import org.eclipse.jetty.servlet.ServletMapping; |
| import org.eclipse.jetty.util.QuotedStringTokenizer; |
| import org.eclipse.jetty.util.log.Log; |
| import org.eclipse.jetty.util.log.Logger; |
| import org.eclipse.jetty.util.resource.Resource; |
| import org.eclipse.jetty.util.security.Constraint; |
| import org.eclipse.jetty.webapp.MetaData; |
| import org.eclipse.jetty.webapp.MetaData.OriginInfo; |
| import org.eclipse.jetty.webapp.MetaInfConfiguration; |
| import org.eclipse.jetty.webapp.WebAppContext; |
| import org.eclipse.jetty.xml.XmlAppendable; |
| |
| /** |
| * QuickStartDescriptorGenerator |
| * <p> |
| * Generate an effective web.xml from a WebAppContext, including all components |
| * from web.xml, web-fragment.xmls annotations etc. |
| */ |
| public class QuickStartDescriptorGenerator |
| { |
| private static final Logger LOG = Log.getLogger(QuickStartDescriptorGenerator.class); |
| |
| public static final String DEFAULT_QUICKSTART_DESCRIPTOR_NAME = "quickstart-web.xml"; |
| |
| protected WebAppContext _webApp; |
| protected String _extraXML; |
| |
| |
| |
| /** |
| * @param w the source WebAppContext |
| * @param extraXML any extra xml snippet to append |
| */ |
| public QuickStartDescriptorGenerator (WebAppContext w, String extraXML) |
| { |
| _webApp = w; |
| _extraXML = extraXML; |
| } |
| |
| |
| /** |
| * Perform the generation of the xml file |
| * @param stream the stream to generate the quickstart-web.xml to |
| * @throws IOException if unable to generate the quickstart-web.xml |
| * @throws FileNotFoundException if unable to find the file |
| */ |
| public void generateQuickStartWebXml (OutputStream stream) throws FileNotFoundException, IOException |
| { |
| if (_webApp == null) |
| throw new IllegalStateException("No webapp for quickstart generation"); |
| if (stream == null) |
| throw new IllegalStateException("No output for quickstart generation"); |
| |
| _webApp.getMetaData().getOrigins(); |
| |
| if (_webApp.getBaseResource()==null) |
| throw new IllegalArgumentException("No base resource for "+this); |
| |
| LOG.info("Quickstart generating"); |
| |
| XmlAppendable out = new XmlAppendable(stream,"UTF-8"); |
| |
| MetaData md = _webApp.getMetaData(); |
| |
| Map<String, String> webappAttr = new HashMap<>(); |
| webappAttr.put("xmlns","http://xmlns.jcp.org/xml/ns/javaee"); |
| webappAttr.put("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"); |
| webappAttr.put("xsi:schemaLocation","http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"); |
| webappAttr.put("metadata-complete","true"); |
| webappAttr.put("version","3.1"); |
| |
| out.openTag("web-app",webappAttr); |
| if (_webApp.getDisplayName() != null) |
| out.tag("display-name",_webApp.getDisplayName()); |
| |
| // Set some special context parameters |
| |
| // The location of the war file on disk |
| AttributeNormalizer normalizer = new AttributeNormalizer(_webApp.getBaseResource()); |
| |
| // The library order |
| addContextParamFromAttribute(out,ServletContext.ORDERED_LIBS); |
| //the servlet container initializers |
| addContextParamFromAttribute(out,AnnotationConfiguration.CONTAINER_INITIALIZERS); |
| //the tlds discovered |
| addContextParamFromAttribute(out,MetaInfConfiguration.METAINF_TLDS,normalizer); |
| //the META-INF/resources discovered |
| addContextParamFromAttribute(out,MetaInfConfiguration.METAINF_RESOURCES,normalizer); |
| |
| |
| // init params |
| for (String p : _webApp.getInitParams().keySet()) |
| out.openTag("context-param",origin(md,"context-param." + p)) |
| .tag("param-name",p) |
| .tag("param-value",_webApp.getInitParameter(p)) |
| .closeTag(); |
| |
| if (_webApp.getEventListeners() != null) |
| for (EventListener e : _webApp.getEventListeners()) |
| out.openTag("listener",origin(md,e.getClass().getCanonicalName() + ".listener")) |
| .tag("listener-class",e.getClass().getCanonicalName()) |
| .closeTag(); |
| |
| ServletHandler servlets = _webApp.getServletHandler(); |
| |
| if (servlets.getFilters() != null) |
| { |
| for (FilterHolder holder : servlets.getFilters()) |
| outholder(out,md,holder); |
| } |
| |
| if (servlets.getFilterMappings() != null) |
| { |
| for (FilterMapping mapping : servlets.getFilterMappings()) |
| { |
| out.openTag("filter-mapping"); |
| out.tag("filter-name",mapping.getFilterName()); |
| if (mapping.getPathSpecs() != null) |
| for (String s : mapping.getPathSpecs()) |
| out.tag("url-pattern",s); |
| if (mapping.getServletNames() != null) |
| for (String n : mapping.getServletNames()) |
| out.tag("servlet-name",n); |
| |
| if (!mapping.isDefaultDispatches()) |
| { |
| if (mapping.appliesTo(DispatcherType.REQUEST)) |
| out.tag("dispatcher","REQUEST"); |
| if (mapping.appliesTo(DispatcherType.ASYNC)) |
| out.tag("dispatcher","ASYNC"); |
| if (mapping.appliesTo(DispatcherType.ERROR)) |
| out.tag("dispatcher","ERROR"); |
| if (mapping.appliesTo(DispatcherType.FORWARD)) |
| out.tag("dispatcher","FORWARD"); |
| if (mapping.appliesTo(DispatcherType.INCLUDE)) |
| out.tag("dispatcher","INCLUDE"); |
| } |
| out.closeTag(); |
| } |
| } |
| |
| if (servlets.getServlets() != null) |
| { |
| for (ServletHolder holder : servlets.getServlets()) |
| outholder(out,md,holder); |
| } |
| |
| if (servlets.getServletMappings() != null) |
| { |
| for (ServletMapping mapping : servlets.getServletMappings()) |
| { |
| out.openTag("servlet-mapping",origin(md,mapping.getServletName() + ".servlet.mappings")); |
| out.tag("servlet-name",mapping.getServletName()); |
| if (mapping.getPathSpecs() != null) |
| for (String s : mapping.getPathSpecs()) |
| out.tag("url-pattern",s); |
| out.closeTag(); |
| } |
| } |
| |
| // Security elements |
| SecurityHandler security =_webApp. getSecurityHandler(); |
| |
| if (security!=null && (security.getRealmName()!=null || security.getAuthMethod()!=null)) |
| { |
| out.openTag("login-config"); |
| if (security.getAuthMethod()!=null) |
| out.tag("auth-method",origin(md,"auth-method"),security.getAuthMethod()); |
| if (security.getRealmName()!=null) |
| out.tag("realm-name",origin(md,"realm-name"),security.getRealmName()); |
| |
| |
| if (Constraint.__FORM_AUTH.equalsIgnoreCase(security.getAuthMethod())) |
| { |
| out.openTag("form-login-config"); |
| out.tag("form-login-page",origin(md,"form-login-page"),security.getInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE)); |
| out.tag("form-error-page",origin(md,"form-error-page"),security.getInitParameter(FormAuthenticator.__FORM_ERROR_PAGE)); |
| out.closeTag(); |
| } |
| |
| out.closeTag(); |
| } |
| |
| if (security instanceof ConstraintAware) |
| { |
| ConstraintAware ca = (ConstraintAware)security; |
| for (String r:ca.getRoles()) |
| out.openTag("security-role") |
| .tag("role-name",r) |
| .closeTag(); |
| |
| for (ConstraintMapping m : ca.getConstraintMappings()) |
| { |
| out.openTag("security-constraint"); |
| |
| out.openTag("web-resource-collection"); |
| { |
| if (m.getConstraint().getName()!=null) |
| out.tag("web-resource-name",m.getConstraint().getName()); |
| if (m.getPathSpec()!=null) |
| out.tag("url-pattern",origin(md,"constraint.url."+m.getPathSpec()),m.getPathSpec()); |
| if (m.getMethod()!=null) |
| out.tag("http-method",m.getMethod()); |
| |
| if (m.getMethodOmissions()!=null) |
| for (String o:m.getMethodOmissions()) |
| out.tag("http-method-omission",o); |
| |
| out.closeTag(); |
| } |
| |
| if (m.getConstraint().getAuthenticate()) |
| { |
| String[] roles = m.getConstraint().getRoles(); |
| if (roles!=null && roles.length>0) |
| { |
| out.openTag("auth-constraint"); |
| if (m.getConstraint().getRoles()!=null) |
| for (String r : m.getConstraint().getRoles()) |
| out.tag("role-name",r); |
| out.closeTag(); |
| } |
| else |
| out.tag("auth-constraint"); |
| } |
| |
| switch (m.getConstraint().getDataConstraint()) |
| { |
| case Constraint.DC_NONE: |
| out.openTag("user-data-constraint").tag("transport-guarantee","NONE").closeTag(); |
| break; |
| |
| case Constraint.DC_INTEGRAL: |
| out.openTag("user-data-constraint").tag("transport-guarantee","INTEGRAL").closeTag(); |
| break; |
| |
| case Constraint.DC_CONFIDENTIAL: |
| out.openTag("user-data-constraint").tag("transport-guarantee","CONFIDENTIAL").closeTag(); |
| break; |
| |
| default: |
| break; |
| |
| } |
| |
| out.closeTag(); |
| |
| } |
| } |
| |
| if (_webApp.getWelcomeFiles() != null) |
| { |
| out.openTag("welcome-file-list"); |
| for (String welcomeFile:_webApp.getWelcomeFiles()) |
| { |
| out.tag("welcome-file", welcomeFile); |
| } |
| out.closeTag(); |
| } |
| |
| Map<String,String> localeEncodings = _webApp.getLocaleEncodings(); |
| if (localeEncodings != null && !localeEncodings.isEmpty()) |
| { |
| out.openTag("locale-encoding-mapping-list"); |
| for (Map.Entry<String, String> entry:localeEncodings.entrySet()) |
| { |
| out.openTag("locale-encoding-mapping", origin(md,"locale-encoding."+entry.getKey())); |
| out.tag("locale", entry.getKey()); |
| out.tag("encoding", entry.getValue()); |
| out.closeTag(); |
| } |
| out.closeTag(); |
| } |
| |
| //session-config |
| if (_webApp.getSessionHandler().getSessionManager() != null) |
| { |
| out.openTag("session-config"); |
| int maxInactiveSec = _webApp.getSessionHandler().getSessionManager().getMaxInactiveInterval(); |
| out.tag("session-timeout", (maxInactiveSec==0?"0":Integer.toString(maxInactiveSec/60))); |
| |
| |
| //cookie-config |
| SessionCookieConfig cookieConfig = _webApp.getSessionHandler().getSessionManager().getSessionCookieConfig(); |
| if (cookieConfig != null) |
| { |
| out.openTag("cookie-config"); |
| if (cookieConfig.getName() != null) |
| out.tag("name", origin(md,"cookie-config.name"), cookieConfig.getName()); |
| |
| if (cookieConfig.getDomain() != null) |
| out.tag("domain", origin(md, "cookie-config.domain"), cookieConfig.getDomain()); |
| |
| if (cookieConfig.getPath() != null) |
| out.tag("path", origin(md, "cookie-config.path"), cookieConfig.getPath()); |
| |
| if (cookieConfig.getComment() != null) |
| out.tag("comment", origin(md, "cookie-config.comment"), cookieConfig.getComment()); |
| |
| out.tag("http-only", origin(md, "cookie-config.http-only"), Boolean.toString(cookieConfig.isHttpOnly())); |
| out.tag("secure", origin(md, "cookie-config.secure"), Boolean.toString(cookieConfig.isSecure())); |
| out.tag("max-age", origin(md, "cookie-config.max-age"), Integer.toString(cookieConfig.getMaxAge())); |
| out.closeTag(); |
| } |
| |
| // tracking-modes |
| Set<SessionTrackingMode> modes =_webApp. getSessionHandler().getSessionManager().getEffectiveSessionTrackingModes(); |
| if (modes != null) |
| { |
| for (SessionTrackingMode mode:modes) |
| out.tag("tracking-mode", mode.toString()); |
| } |
| |
| out.closeTag(); |
| } |
| |
| //error-pages |
| Map<String,String> errorPages = ((ErrorPageErrorHandler)_webApp.getErrorHandler()).getErrorPages(); |
| if (errorPages != null) |
| { |
| for (Map.Entry<String, String> entry:errorPages.entrySet()) |
| { |
| out.openTag("error-page", origin(md, "error."+entry.getKey())); |
| //a global or default error page has no code or exception |
| if (!ErrorPageErrorHandler.GLOBAL_ERROR_PAGE.equals(entry.getKey())) |
| { |
| if (entry.getKey().matches("\\d{3}")) |
| out.tag("error-code", entry.getKey()); |
| else |
| out.tag("exception-type", entry.getKey()); |
| } |
| out.tag("location", entry.getValue()); |
| out.closeTag(); |
| } |
| } |
| |
| //mime-types |
| MimeTypes mimeTypes = _webApp.getMimeTypes(); |
| if (mimeTypes != null) |
| { |
| for (Map.Entry<String, String> entry:mimeTypes.getMimeMap().entrySet()) |
| { |
| out.openTag("mime-mapping"); |
| out.tag("extension", origin(md, "extension."+entry.getKey()), entry.getKey()); |
| out.tag("mime-type", entry.getValue()); |
| out.closeTag(); |
| } |
| } |
| |
| //jsp-config |
| JspConfig jspConfig = (JspConfig)_webApp.getServletContext().getJspConfigDescriptor(); |
| if (jspConfig != null) |
| { |
| out.openTag("jsp-config"); |
| Collection<TaglibDescriptor> tlds = jspConfig.getTaglibs(); |
| if (tlds != null && !tlds.isEmpty()) |
| { |
| for (TaglibDescriptor tld:tlds) |
| { |
| out.openTag("taglib"); |
| out.tag("taglib-uri", tld.getTaglibURI()); |
| out.tag("taglib-location", tld.getTaglibLocation()); |
| out.closeTag(); |
| } |
| } |
| |
| Collection<JspPropertyGroupDescriptor> jspPropertyGroups = jspConfig.getJspPropertyGroups(); |
| if (jspPropertyGroups != null && !jspPropertyGroups.isEmpty()) |
| { |
| for (JspPropertyGroupDescriptor jspPropertyGroup:jspPropertyGroups) |
| { |
| out.openTag("jsp-property-group"); |
| Collection<String> strings = jspPropertyGroup.getUrlPatterns(); |
| if (strings != null && !strings.isEmpty()) |
| { |
| for (String urlPattern:strings) |
| out.tag("url-pattern", urlPattern); |
| } |
| |
| if (jspPropertyGroup.getElIgnored() != null) |
| out.tag("el-ignored", jspPropertyGroup.getElIgnored()); |
| |
| if (jspPropertyGroup.getPageEncoding() != null) |
| out.tag("page-encoding", jspPropertyGroup.getPageEncoding()); |
| |
| if (jspPropertyGroup.getScriptingInvalid() != null) |
| out.tag("scripting-invalid", jspPropertyGroup.getScriptingInvalid()); |
| |
| if (jspPropertyGroup.getIsXml() != null) |
| out.tag("is-xml", jspPropertyGroup.getIsXml()); |
| |
| if (jspPropertyGroup.getDeferredSyntaxAllowedAsLiteral() != null) |
| out.tag("deferred-syntax-allowed-as-literal", jspPropertyGroup.getDeferredSyntaxAllowedAsLiteral()); |
| |
| if (jspPropertyGroup.getTrimDirectiveWhitespaces() != null) |
| out.tag("trim-directive-whitespaces", jspPropertyGroup.getTrimDirectiveWhitespaces()); |
| |
| if (jspPropertyGroup.getDefaultContentType() != null) |
| out.tag("default-content-type", jspPropertyGroup.getDefaultContentType()); |
| |
| if (jspPropertyGroup.getBuffer() != null) |
| out.tag("buffer", jspPropertyGroup.getBuffer()); |
| |
| if (jspPropertyGroup.getErrorOnUndeclaredNamespace() != null) |
| out.tag("error-on-undeclared-namespace", jspPropertyGroup.getErrorOnUndeclaredNamespace()); |
| |
| strings = jspPropertyGroup.getIncludePreludes(); |
| if (strings != null && !strings.isEmpty()) |
| { |
| for (String prelude:strings) |
| out.tag("include-prelude", prelude); |
| } |
| |
| strings = jspPropertyGroup.getIncludeCodas(); |
| if (strings != null && !strings.isEmpty()) |
| { |
| for (String coda:strings) |
| out.tag("include-coda", coda); |
| } |
| |
| out.closeTag(); |
| } |
| } |
| |
| out.closeTag(); |
| } |
| |
| //lifecycle: post-construct, pre-destroy |
| LifeCycleCallbackCollection lifecycles = ((LifeCycleCallbackCollection)_webApp.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION)); |
| if (lifecycles != null) |
| { |
| Collection<LifeCycleCallback> tmp = lifecycles.getPostConstructCallbacks(); |
| |
| for (LifeCycleCallback c:tmp) |
| { |
| out.openTag("post-construct"); |
| out.tag("lifecycle-callback-class", c.getTargetClassName()); |
| out.tag("lifecycle-callback-method", c.getMethodName()); |
| out.closeTag(); |
| } |
| |
| tmp = lifecycles.getPreDestroyCallbacks(); |
| for (LifeCycleCallback c:tmp) |
| { |
| out.openTag("pre-destroy"); |
| out.tag("lifecycle-callback-class", c.getTargetClassName()); |
| out.tag("lifecycle-callback-method", c.getMethodName()); |
| out.closeTag(); |
| } |
| } |
| |
| out.literal(_extraXML); |
| |
| out.closeTag(); |
| } |
| |
| /** |
| * Turn attribute into context-param to store. |
| * |
| * @param out |
| * @param attribute |
| * @throws IOException |
| */ |
| private void addContextParamFromAttribute(XmlAppendable out, String attribute) throws IOException |
| { |
| Object o = _webApp.getAttribute(attribute); |
| if (o == null) |
| return; |
| |
| Collection<?> c = (o instanceof Collection)? (Collection<?>)o:Collections.singletonList(o); |
| StringBuilder v=new StringBuilder(); |
| for (Object i:c) |
| { |
| if (i!=null) |
| { |
| if (v.length()>0) |
| v.append(",\n "); |
| else |
| v.append("\n "); |
| QuotedStringTokenizer.quote(v,i.toString()); |
| } |
| } |
| out.openTag("context-param") |
| .tag("param-name",attribute) |
| .tagCDATA("param-value",v.toString()) |
| .closeTag(); |
| } |
| |
| /** |
| * Turn context attribute into context-param to store. |
| * |
| * @param out |
| * @param attribute |
| * @param resourceBase |
| * @throws IOException |
| */ |
| private void addContextParamFromAttribute(XmlAppendable out, String attribute, AttributeNormalizer normalizer) throws IOException |
| { |
| Object o = _webApp.getAttribute(attribute); |
| if (o == null) |
| return; |
| |
| Collection<?> c = (o instanceof Collection)? (Collection<?>)o:Collections.singletonList(o); |
| StringBuilder v=new StringBuilder(); |
| for (Object i:c) |
| { |
| if (i!=null) |
| { |
| if (v.length()>0) |
| v.append(",\n "); |
| else |
| v.append("\n "); |
| QuotedStringTokenizer.quote(v,normalizer.normalize(i)); |
| } |
| } |
| out.openTag("context-param") |
| .tag("param-name",attribute) |
| .tagCDATA("param-value",v.toString()) |
| .closeTag(); |
| |
| } |
| |
| /** |
| * Generate xml for a Holder (Filter/Servlet) |
| * |
| * @param out |
| * @param md |
| * @param tag |
| * @param holder |
| * @throws IOException |
| */ |
| private void outholder(XmlAppendable out, MetaData md, FilterHolder holder) throws IOException |
| { |
| if (LOG.isDebugEnabled()) |
| out.openTag("filter",Collections.singletonMap("source",holder.getSource().toString())); |
| else |
| out.openTag("filter"); |
| |
| String n = holder.getName(); |
| out.tag("filter-name",n); |
| |
| String ot = n + ".filter."; |
| |
| if (holder instanceof FilterHolder) |
| { |
| out.tag("filter-class",origin(md,ot + "filter-class"),holder.getClassName()); |
| out.tag("async-supported",origin(md,ot + "async-supported"),holder.isAsyncSupported()?"true":"false"); |
| } |
| |
| for (String p : holder.getInitParameters().keySet()) |
| { |
| out.openTag("init-param",origin(md,ot + "init-param." + p)) |
| .tag("param-name",p) |
| .tag("param-value",holder.getInitParameter(p)) |
| .closeTag(); |
| } |
| |
| out.closeTag(); |
| } |
| |
| private void outholder(XmlAppendable out, MetaData md, ServletHolder holder) throws IOException |
| { |
| |
| if (LOG.isDebugEnabled()) |
| out.openTag("servlet",Collections.singletonMap("source",holder.getSource().toString())); |
| else |
| out.openTag("servlet"); |
| |
| String n = holder.getName(); |
| out.tag("servlet-name",n); |
| |
| String ot = n + ".servlet."; |
| |
| ServletHolder s = (ServletHolder)holder; |
| if (s.getForcedPath() != null && s.getClassName() == null) |
| out.tag("jsp-file",s.getForcedPath()); |
| else |
| out.tag("servlet-class",origin(md,ot + "servlet-class"),s.getClassName()); |
| |
| for (String p : holder.getInitParameters().keySet()) |
| { |
| if ("jsp".equalsIgnoreCase(n) && "scratchdir".equalsIgnoreCase(p)) //don't preconfigure the temp dir for jsp output |
| continue; |
| out.openTag("init-param",origin(md,ot + "init-param." + p)) |
| .tag("param-name",p) |
| .tag("param-value",holder.getInitParameter(p)) |
| .closeTag(); |
| } |
| |
| if (s.getInitOrder() >= 0) |
| out.tag("load-on-startup",Integer.toString(s.getInitOrder())); |
| |
| if (!s.isEnabled()) |
| out.tag("enabled",origin(md,ot + "enabled"),"false"); |
| |
| out.tag("async-supported",origin(md,ot + "async-supported"),holder.isAsyncSupported()?"true":"false"); |
| |
| if (s.getRunAsRole() != null) |
| out.openTag("run-as",origin(md,ot + "run-as")) |
| .tag("role-name",s.getRunAsRole()) |
| .closeTag(); |
| |
| Map<String,String> roles = s.getRoleRefMap(); |
| if (roles!=null) |
| { |
| for (Map.Entry<String, String> e : roles.entrySet()) |
| { |
| out.openTag("security-role-ref",origin(md,ot+"role-name."+e.getKey())) |
| .tag("role-name",e.getKey()) |
| .tag("role-link",e.getValue()) |
| .closeTag(); |
| } |
| } |
| |
| //multipart-config |
| MultipartConfigElement multipartConfig = ((ServletHolder.Registration)s.getRegistration()).getMultipartConfig(); |
| if (multipartConfig != null) |
| { |
| out.openTag("multipart-config", origin(md, s.getName()+".servlet.multipart-config")); |
| if (multipartConfig.getLocation() != null) |
| out.tag("location", multipartConfig.getLocation()); |
| out.tag("max-file-size", Long.toString(multipartConfig.getMaxFileSize())); |
| out.tag("max-request-size", Long.toString(multipartConfig.getMaxRequestSize())); |
| out.tag("file-size-threshold", Long.toString(multipartConfig.getFileSizeThreshold())); |
| out.closeTag(); |
| } |
| |
| out.closeTag(); |
| } |
| |
| |
| /** |
| * Find the origin (web.xml, fragment, annotation etc) of a web artifact from MetaData. |
| * |
| * @param md the metadata |
| * @param name the name |
| * @return the origin map |
| */ |
| public Map<String, String> origin(MetaData md, String name) |
| { |
| if (!LOG.isDebugEnabled()) |
| return Collections.emptyMap(); |
| if (name == null) |
| return Collections.emptyMap(); |
| OriginInfo origin = md.getOriginInfo(name); |
| if (LOG.isDebugEnabled()) LOG.debug("origin of "+name+" is "+origin); |
| if (origin == null) |
| return Collections.emptyMap(); |
| return Collections.singletonMap("origin",origin.toString()); |
| } |
| |
| } |