From c674c410031fdcc19aea67e9375f9ecfae1b4f67 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 10 Jul 2014 17:28:09 +1000 Subject: [PATCH] 438895 Add mvn jetty:effective-web-xml goal --- .../maven/plugin/JettyEffectiveWebXml.java | 157 ++++ .../maven/plugin/JettyRunForkedMojo.java | 22 +- .../maven/plugin/JettyWebAppContext.java | 30 +- .../QuickStartDescriptorGenerator.java | 749 +++++++++--------- .../jetty/quickstart/QuickStartWebApp.java | 14 +- 5 files changed, 569 insertions(+), 403 deletions(-) create mode 100644 jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java new file mode 100644 index 00000000000..6c607c85df5 --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java @@ -0,0 +1,157 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 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.maven.plugin; + +import java.io.File; +import java.io.IOException; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.eclipse.jetty.annotations.AnnotationConfiguration; +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.thread.QueuedThreadPool; + +/** + * JettyEffectiveWebXml + * + * @goal effective-web-xml + * @requiresDependencyResolution test + * @execute phase="test-compile" + * @description Runs jetty on the unassembled webapp to generate the effective web.xml + */ +public class JettyEffectiveWebXml extends JettyRunMojo +{ + /** + * The target directory + * + * @parameter expression="${project.build.directory}" + * @required + * @readonly + */ + protected File target; + + /** + * The target directory + * + * @parameter + */ + protected File effectiveWebXml; + + + protected boolean deleteOnExit = true; + + + /** + * @see org.apache.maven.plugin.Mojo#execute() + */ + public void execute() throws MojoExecutionException, MojoFailureException + { + super.execute(); + } + + + @Override + public void startJetty() throws MojoExecutionException + { + //Only do enough setup to be able to produce a quickstart-web.xml file to + //pass onto the forked process to run + + //if the user didn't nominate a file to generate into, pick the name and + //make sure that it is deleted on exit + if (effectiveWebXml == null) + { + deleteOnExit = true; + effectiveWebXml = new File(target, "effective-web.xml"); + effectiveWebXml.deleteOnExit(); + } + + Resource descriptor = Resource.newResource(effectiveWebXml); + + QueuedThreadPool tpool = null; + + try + { + printSystemProperties(); + + //apply any config from a jetty.xml file first to our "fake" server instance + //TODO probably not necessary + applyJettyXml (); + + + server.configureHandlers(); + + //ensure config of the webapp based on settings in plugin + configureWebApplication(); + + + //set the webapp up to do very little other than generate the quickstart-web.xml + webApp.setCopyWebDir(false); + webApp.setCopyWebInf(false); + webApp.setGenerateQuickStart(true); + + if (!effectiveWebXml.getParentFile().exists()) + effectiveWebXml.getParentFile().mkdirs(); + if (!effectiveWebXml.exists()) + effectiveWebXml.createNewFile(); + + webApp.setQuickStartWebDescriptor(descriptor); + + server.addWebApplication(webApp); + + //if our server has a thread pool associated we can do any annotation scanning multithreaded, + //otherwise scanning will be single threaded + tpool = server.getBean(QueuedThreadPool.class); + if (tpool != null) + tpool.start(); + else + webApp.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE.toString()); + + webApp.start(); //just enough to generate the quickstart + + } + catch (Exception e) + { + throw new MojoExecutionException("Effective web.xml generation failed", e); + } + finally + { + try {webApp.stop();}catch (Exception x) {}; + + try {if (tpool != null) tpool.stop();} catch (Exception x) {}; + } + + + if (deleteOnExit) + { + try + { + //just show the result in the log + getLog().info(IO.toString(descriptor.getInputStream())); + } + catch (IOException e) + { + throw new MojoExecutionException("Unable to output effective web.xml", e); + } + + } + + } +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunForkedMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunForkedMojo.java index 663749d033e..aa73a33860f 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunForkedMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunForkedMojo.java @@ -43,6 +43,7 @@ import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.eclipse.jetty.annotations.AnnotationConfiguration; +import org.eclipse.jetty.quickstart.QuickStartDescriptorGenerator; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceCollection; @@ -98,6 +99,13 @@ public class JettyRunForkedMojo extends JettyRunMojo */ protected File target; + /** + * The file into which to generate the quickstart web xml for the forked process to use + * + * @parameter expression="${project.build.directory}/fork-web.xml" + */ + protected File forkWebXml; + /** * Arbitrary jvm args to pass to the forked process @@ -229,7 +237,11 @@ public class JettyRunForkedMojo extends JettyRunMojo public void startJetty() throws MojoExecutionException { //Only do enough setup to be able to produce a quickstart-web.xml file to - //pass onto the forked process to run + //pass onto the forked process to run + + if (forkWebXml == null) + forkWebXml = new File (target, "fork-web.xml"); + try { printSystemProperties(); @@ -251,7 +263,13 @@ public class JettyRunForkedMojo extends JettyRunMojo webApp.setCopyWebDir(false); webApp.setCopyWebInf(false); webApp.setGenerateQuickStart(true); - webApp.setQuickStartDir(target); + + if (!forkWebXml.getParentFile().exists()) + forkWebXml.getParentFile().mkdirs(); + if (!forkWebXml.exists()) + forkWebXml.createNewFile(); + + webApp.setQuickStartWebDescriptor(Resource.newResource(forkWebXml)); server.addWebApplication(webApp); diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyWebAppContext.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyWebAppContext.java index 4b8a76bc7d9..4ba0c8b88cd 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyWebAppContext.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyWebAppContext.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.maven.plugin; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.util.ArrayList; @@ -125,7 +126,7 @@ public class JettyWebAppContext extends WebAppContext private boolean _isGenerateQuickStart; private PreconfigureDescriptorProcessor _preconfigProcessor; - private File _quickStartDir; + @@ -274,15 +275,7 @@ public class JettyWebAppContext extends WebAppContext return _isGenerateQuickStart; } - public void setQuickStartDir (File dir) - { - _quickStartDir = dir; - } - - public File getQuickStartDir() - { - return _quickStartDir; - } + @Override @@ -290,9 +283,14 @@ public class JettyWebAppContext extends WebAppContext { if (isGenerateQuickStart()) { - QuickStartDescriptorGenerator generator = new QuickStartDescriptorGenerator(this, (getQuickStartDir()==null?getTempDirectory():getQuickStartDir()), _preconfigProcessor.getXML()); - File f = generator.generateQuickStartWebXml(); - setQuickStartWebDescriptor(Resource.newResource(f)); + if (getQuickStartWebDescriptor() == null) + throw new IllegalStateException ("No location to generate quickstart descriptor"); + + QuickStartDescriptorGenerator generator = new QuickStartDescriptorGenerator(this, _preconfigProcessor.getXML()); + try (FileOutputStream fos = new FileOutputStream(getQuickStartWebDescriptor().getFile())) + { + generator.generateQuickStartWebXml(fos); + } } else super.startWebapp(); @@ -303,7 +301,9 @@ public class JettyWebAppContext extends WebAppContext public void doStart () throws Exception { //choose if this will be a quickstart or normal start - if (getQuickStartWebDescriptor() == null) + if (!isGenerateQuickStart() && getQuickStartWebDescriptor() != null) + setConfigurations(_quickStartConfigurations); + else { setConfigurations(_defaultConfigurations); if (isGenerateQuickStart()) @@ -312,8 +312,6 @@ public class JettyWebAppContext extends WebAppContext getMetaData().addDescriptorProcessor(_preconfigProcessor); } } - else - setConfigurations(_quickStartConfigurations); //inject configurations with config from maven plugin diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorGenerator.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorGenerator.java index a138ae6e577..27cbf1bb4fa 100644 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorGenerator.java +++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartDescriptorGenerator.java @@ -23,6 +23,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.util.Collection; import java.util.Collections; import java.util.EventListener; @@ -75,21 +76,21 @@ import org.eclipse.jetty.xml.XmlAppendable; 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 File _descriptorDir; protected String _extraXML; /** * @param w the source WebAppContext - * @param descriptorDir the directory where quickstart-web.xml should be saved * @param extraXML any extra xml snippet to append */ - public QuickStartDescriptorGenerator (WebAppContext w, File descriptorDir, String extraXML) + public QuickStartDescriptorGenerator (WebAppContext w, String extraXML) { _webApp = w; - _descriptorDir = descriptorDir; _extraXML = extraXML; } @@ -100,424 +101,406 @@ public class QuickStartDescriptorGenerator * @throws FileNotFoundException * @throws Exception */ - public File generateQuickStartWebXml () throws FileNotFoundException, IOException + public void generateQuickStartWebXml (OutputStream stream) throws FileNotFoundException, IOException { if (_webApp == null) - throw new IllegalStateException("No webapp for quickstart-web.xml"); - if (_descriptorDir == null) - throw new IllegalStateException("No location for quickstart-web.xml"); + 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); - if (!_descriptorDir.exists()) - _descriptorDir.mkdirs(); - - File webXml = new File(_descriptorDir,"quickstart-web.xml"); - - LOG.info("Quickstart generate {}",webXml); - - try (FileOutputStream fos = new FileOutputStream(webXml)) - { - XmlAppendable out = new XmlAppendable(fos,"UTF-8"); + LOG.info("Quickstart generating"); - MetaData md = _webApp.getMetaData(); + XmlAppendable out = new XmlAppendable(stream,"UTF-8"); - Map 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"); + MetaData md = _webApp.getMetaData(); - out.openTag("web-app",webappAttr); - if (_webApp.getDisplayName() != null) - out.tag("display-name",_webApp.getDisplayName()); + Map 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"); - // Set some special context parameters + out.openTag("web-app",webappAttr); + if (_webApp.getDisplayName() != null) + out.tag("display-name",_webApp.getDisplayName()); - // The location of the war file on disk - String resourceBase = _webApp.getBaseResource().getFile().getCanonicalFile().getAbsoluteFile().toURI().toString(); + // Set some special context parameters - // 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,resourceBase); - //the META-INF/resources discovered - addContextParamFromAttribute(out,MetaInfConfiguration.METAINF_RESOURCES,resourceBase); + // The location of the war file on disk + String resourceBase = _webApp.getBaseResource().getFile().getCanonicalFile().getAbsoluteFile().toURI().toString(); + + // 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,resourceBase); + //the META-INF/resources discovered + addContextParamFromAttribute(out,MetaInfConfiguration.METAINF_RESOURCES,resourceBase); - // 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)) + // 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(); - 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(); - ServletHandler servlets = _webApp.getServletHandler(); + if (servlets.getFilters() != null) + { + for (FilterHolder holder : servlets.getFilters()) + outholder(out,md,"filter",holder); + } - if (servlets.getFilters() != null) + if (servlets.getFilterMappings() != null) + { + for (FilterMapping mapping : servlets.getFilterMappings()) { - for (FilterHolder holder : servlets.getFilters()) - outholder(out,md,"filter",holder); - } + 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 (servlets.getFilterMappings() != null) - { - for (FilterMapping mapping : servlets.getFilterMappings()) + if (!mapping.isDefaultDispatches()) { - 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,"servlet",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"); - - if (m.getConstraint().getAuthenticate()) - { - out.openTag("auth-constraint"); - if (m.getConstraint().getRoles()!=null) - for (String r : m.getConstraint().getRoles()) - out.tag("role-name",r); - - out.closeTag(); - } - - 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.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(); - } - - out.closeTag(); - - } - } - - if (_webApp.getWelcomeFiles() != null) - { - out.openTag("welcome-file-list"); - for (String welcomeFile:_webApp.getWelcomeFiles()) - { - out.tag("welcome-file", welcomeFile); + 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(); } + } - Map localeEncodings = _webApp.getLocaleEncodings(); - if (localeEncodings != null && !localeEncodings.isEmpty()) + if (servlets.getServlets() != null) + { + for (ServletHolder holder : servlets.getServlets()) + outholder(out,md,"servlet",holder); + } + + if (servlets.getServletMappings() != null) + { + for (ServletMapping mapping : servlets.getServletMappings()) { - out.openTag("locale-encoding-mapping-list"); - for (Map.Entry 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.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(); } + } - //session-config - if (_webApp.getSessionHandler().getSessionManager() != null) + // 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("session-config"); - int maxInactiveSec = _webApp.getSessionHandler().getSessionManager().getMaxInactiveInterval(); - out.tag("session-timeout", (maxInactiveSec==0?"0":Integer.toString(maxInactiveSec/60))); - - Set modes =_webApp. getSessionHandler().getSessionManager().getEffectiveSessionTrackingModes(); - if (modes != null) - { - for (SessionTrackingMode mode:modes) - out.tag("tracking-mode", mode.toString()); - } - - //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(); - } - out.closeTag(); - } - - //error-pages - Map errorPages = ((ErrorPageErrorHandler)_webApp.getErrorHandler()).getErrorPages(); - if (errorPages != null) - { - for (Map.Entry 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 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 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 jspPropertyGroups = jspConfig.getJspPropertyGroups(); - if (jspPropertyGroups != null && !jspPropertyGroups.isEmpty()) - { - for (JspPropertyGroupDescriptor jspPropertyGroup:jspPropertyGroups) - { - out.openTag("jsp-property-group"); - Collection 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.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(); } - //lifecycle: post-construct, pre-destroy - LifeCycleCallbackCollection lifecycles = ((LifeCycleCallbackCollection)_webApp.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION)); - if (lifecycles != null) - { - Collection 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(); } - catch (Exception e) + + if (security instanceof ConstraintAware) { - if (e.getSuppressed() != null) - { - for (Throwable t:e.getSuppressed()) - t.printStackTrace(); - } + 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"); + + if (m.getConstraint().getAuthenticate()) + { + out.openTag("auth-constraint"); + if (m.getConstraint().getRoles()!=null) + for (String r : m.getConstraint().getRoles()) + out.tag("role-name",r); + + out.closeTag(); + } + + 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.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(); + } + + out.closeTag(); + + } } - - return webXml; + + if (_webApp.getWelcomeFiles() != null) + { + out.openTag("welcome-file-list"); + for (String welcomeFile:_webApp.getWelcomeFiles()) + { + out.tag("welcome-file", welcomeFile); + } + out.closeTag(); + } + + Map localeEncodings = _webApp.getLocaleEncodings(); + if (localeEncodings != null && !localeEncodings.isEmpty()) + { + out.openTag("locale-encoding-mapping-list"); + for (Map.Entry 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))); + + Set modes =_webApp. getSessionHandler().getSessionManager().getEffectiveSessionTrackingModes(); + if (modes != null) + { + for (SessionTrackingMode mode:modes) + out.tag("tracking-mode", mode.toString()); + } + + //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(); + } + out.closeTag(); + } + + //error-pages + Map errorPages = ((ErrorPageErrorHandler)_webApp.getErrorHandler()).getErrorPages(); + if (errorPages != null) + { + for (Map.Entry 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 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 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 jspPropertyGroups = jspConfig.getJspPropertyGroups(); + if (jspPropertyGroups != null && !jspPropertyGroups.isEmpty()) + { + for (JspPropertyGroupDescriptor jspPropertyGroup:jspPropertyGroups) + { + out.openTag("jsp-property-group"); + Collection 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 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(); } /** diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartWebApp.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartWebApp.java index 959cf8015c1..0372e52cb99 100644 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartWebApp.java +++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/QuickStartWebApp.java @@ -18,6 +18,8 @@ package org.eclipse.jetty.quickstart; +import java.io.FileOutputStream; + import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.JarResource; @@ -32,6 +34,8 @@ public class QuickStartWebApp extends WebAppContext { private static final Logger LOG = Log.getLogger(QuickStartWebApp.class); + + public static final String[] __configurationClasses = new String[] { org.eclipse.jetty.quickstart.QuickStartConfiguration.class.getCanonicalName(), @@ -164,8 +168,14 @@ public class QuickStartWebApp extends WebAppContext public void generateQuickstartWebXml(String extraXML) throws Exception { - QuickStartDescriptorGenerator generator = new QuickStartDescriptorGenerator(this, this.getWebInf().getFile(), extraXML); - generator.generateQuickStartWebXml(); + Resource descriptor = getWebInf().addPath(QuickStartDescriptorGenerator.DEFAULT_QUICKSTART_DESCRIPTOR_NAME); + if (!descriptor.exists()) + descriptor.getFile().createNewFile(); + QuickStartDescriptorGenerator generator = new QuickStartDescriptorGenerator(this, extraXML); + try (FileOutputStream fos = new FileOutputStream(descriptor.getFile())) + { + generator.generateQuickStartWebXml(fos); + } }