* where there is duplicate configuration, the most specific level wins. ie
* an application's web.xml takes precedence over the host level or global
* web.xml file.
*/
protected void webConfig() {
WebXml webXml = createWebXml();
// Parse global web.xml if present
InputSource globalWebXml = getGlobalWebXmlSource();
if (globalWebXml == null) {
// This is unusual enough to log
log.info(sm.getString("contextConfig.defaultMissing"));
} else {
parseWebXml(globalWebXml, webXml, false);
}
// Parse host level web.xml if present
// Additive apart from welcome pages
webXml.setReplaceWelcomeFiles(true);
InputSource hostWebXml = getHostWebXmlSource();
parseWebXml(hostWebXml, webXml, false);
// Parse context level web.xml
webXml.setReplaceWelcomeFiles(true);
InputSource contextWebXml = getContextWebXmlSource();
parseWebXml(contextWebXml, webXml, false);
// Assuming 0 is safe for what is required in this case
double webXmlVersion = 0;
if (webXml.getVersion() != null) {
webXmlVersion = Double.parseDouble(webXml.getVersion());
}
if (webXmlVersion >= 3) {
// Ordering is important here
// Step 1. Identify all the JARs packaged with the application
// If the JARs have a web-fragment.xml it will be parsed at this
// point.
Map<String,WebXml> fragments = processJarsForWebFragments();
// Only need to process fragments and annotations if metadata is
// not complete
Set<WebXml> orderedFragments = null;
if (!webXml.isMetadataComplete()) {
// Step 2. Order the fragments.
orderedFragments = WebXml.orderWebFragments(webXml, fragments);
// Step 3. Look for ServletContainerInitializer implementations
if (ok) {
processServletContainerInitializers(orderedFragments);
}
// Step 4. Process /WEB-INF/classes for annotations
// This will add any matching classes to the typeInitializerMap
if (ok) {
URL webinfClasses;
try {
webinfClasses = context.getServletContext().getResource(
"/WEB-INF/classes");
processAnnotationsUrl(webinfClasses, webXml);
} catch (MalformedURLException e) {
log.error(sm.getString(
"contextConfig.webinfClassesUrl"), e);
}
}
// Step 5. Process JARs for annotations - only need to process
// those fragments we are going to use
// This will add any matching classes to the typeInitializerMap
if (ok) {
processAnnotations(orderedFragments);
}
// Step 6. Merge web-fragment.xml files into the main web.xml
// file.
if (ok) {
ok = webXml.merge(orderedFragments);
}
// Step 6.5 Convert explicitly mentioned jsps to servlets
if (!false) {
convertJsps(webXml);
}
// Step 7. Apply merged web.xml to Context
if (ok) {
webXml.configureContext(context);
// Step 7a. Make the merged web.xml available to other
// components, specifically Jasper, to save those components
// from having to re-generate it.
// TODO Use a ServletContainerInitializer for Jasper
String mergedWebXml = webXml.toXml();
context.getServletContext().setAttribute(
org.apache.tomcat.util.scan.Constants.MERGED_WEB_XML,
mergedWebXml);
if (context.getLogEffectiveWebXml()) {
log.info("web.xml:\n" + mergedWebXml);
}
}
} else {
webXml.configureContext(context);
}
// Always need to look for static resources
// Step 8. Look for static resources packaged in JARs
if (ok) {
// Spec does not define an order.
// Use ordered JARs followed by remaining JARs
Set<WebXml> resourceJars = new LinkedHashSet<WebXml>();
if (orderedFragments != null) {
for (WebXml fragment : orderedFragments) {
resourceJars.add(fragment);
}
}
for (WebXml fragment : fragments.values()) {
if (!resourceJars.contains(fragment)) {
resourceJars.add(fragment);
}
}
processResourceJARs(resourceJars);
// See also StandardContext.resourcesStart() for
// WEB-INF/classes/META-INF/resources configuration
}
// Only look for ServletContainerInitializer if metadata is not
// complete
if (!webXml.isMetadataComplete()) {
// Step 9. Apply the ServletContainerInitializer config to the
// context
if (ok) {
for (Map.Entry<ServletContainerInitializer,
Set<Class<?>>> entry :
initializerClassMap.entrySet()) {
if (entry.getValue().isEmpty()) {
context.addServletContainerInitializer(
entry.getKey(), null);
} else {
context.addServletContainerInitializer(
entry.getKey(), entry.getValue());
}
}
}
}
} else {
// Apply unmerged web.xml to Context
convertJsps(webXml);
webXml.configureContext(context);
}
}