All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.webapp.MetaInfConfiguration Maven / Gradle / Ivy

There is a newer version: 11.0.0.beta1
Show newest version
//
//  ========================================================================
//  Copyright (c) 1995-2015 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.webapp;


import java.net.URI;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.EmptyResource;
import org.eclipse.jetty.util.resource.Resource;

/**
 * MetaInfConfiguration
 *
 * Scan META-INF of jars to find:
 * 
    *
  • tlds *
  • web-fragment.xml *
  • resources *
* * The jars which are scanned are: *
    *
  1. those from the container classpath whose pattern matched the WebInfConfiguration.CONTAINER_JAR_PATTERN
  2. *
  3. those from WEB-INF/lib
  4. *
*/ public class MetaInfConfiguration extends AbstractConfiguration { private static final Logger LOG = Log.getLogger(MetaInfConfiguration.class); public static final String USE_CONTAINER_METAINF_CACHE = "org.eclipse.jetty.metainf.useCache"; public static final boolean DEFAULT_USE_CONTAINER_METAINF_CACHE = true; public static final String CACHED_CONTAINER_TLDS = "org.eclipse.jetty.tlds.cache"; public static final String CACHED_CONTAINER_FRAGMENTS = FragmentConfiguration.FRAGMENT_RESOURCES+".cache"; public static final String CACHED_CONTAINER_RESOURCES = WebInfConfiguration.RESOURCE_DIRS+".cache"; public static final String METAINF_TLDS = "org.eclipse.jetty.tlds"; public static final String METAINF_FRAGMENTS = FragmentConfiguration.FRAGMENT_RESOURCES; public static final String METAINF_RESOURCES = WebInfConfiguration.RESOURCE_DIRS; @Override public void preConfigure(final WebAppContext context) throws Exception { boolean useContainerCache = DEFAULT_USE_CONTAINER_METAINF_CACHE; Boolean attr = (Boolean)context.getServer().getAttribute(USE_CONTAINER_METAINF_CACHE); if (attr != null) useContainerCache = attr.booleanValue(); if (LOG.isDebugEnabled()) LOG.debug("{} = {}", USE_CONTAINER_METAINF_CACHE, useContainerCache); //pre-emptively create empty lists for tlds, fragments and resources as context attributes //this signals that this class has been called. This differentiates the case where this class //has been called but finds no META-INF data from the case where this class was never called if (context.getAttribute(METAINF_TLDS) == null) context.setAttribute(METAINF_TLDS, new HashSet()); if (context.getAttribute(METAINF_RESOURCES) == null) context.setAttribute(METAINF_RESOURCES, new HashSet()); if (context.getAttribute(METAINF_FRAGMENTS) == null) context.setAttribute(METAINF_FRAGMENTS, new HashMap()); scanJars(context, context.getMetaData().getContainerResources(), useContainerCache); scanJars(context, context.getMetaData().getWebInfJars(), false); } /** * Look into the jars to discover info in META-INF. If useCaches == true, then we will * cache the info discovered indexed by the jar in which it was discovered: this speeds * up subsequent context deployments. * * @param context * @param jars * @param useCaches * @throws Exception */ public void scanJars (final WebAppContext context, Collection jars, boolean useCaches) throws Exception { ConcurrentHashMap metaInfResourceCache = null; ConcurrentHashMap metaInfFragmentCache = null; ConcurrentHashMap> metaInfTldCache = null; if (useCaches) { metaInfResourceCache = (ConcurrentHashMap)context.getServer().getAttribute(CACHED_CONTAINER_RESOURCES); if (metaInfResourceCache == null) { metaInfResourceCache = new ConcurrentHashMap(); context.getServer().setAttribute(CACHED_CONTAINER_RESOURCES, metaInfResourceCache); } metaInfFragmentCache = (ConcurrentHashMap)context.getServer().getAttribute(CACHED_CONTAINER_FRAGMENTS); if (metaInfFragmentCache == null) { metaInfFragmentCache = new ConcurrentHashMap(); context.getServer().setAttribute(CACHED_CONTAINER_FRAGMENTS, metaInfFragmentCache); } metaInfTldCache = (ConcurrentHashMap>)context.getServer().getAttribute(CACHED_CONTAINER_TLDS); if (metaInfTldCache == null) { metaInfTldCache = new ConcurrentHashMap>(); context.getServer().setAttribute(CACHED_CONTAINER_TLDS, metaInfTldCache); } } //Scan jars for META-INF information if (jars != null) { for (Resource r : jars) { scanForResources(context, r, metaInfResourceCache); scanForFragment(context, r, metaInfFragmentCache); scanForTlds(context, r, metaInfTldCache); } } } /** * Scan for META-INF/resources dir in the given jar. * * @param context * @param target * @param cache * @throws Exception */ public void scanForResources (WebAppContext context, Resource target, ConcurrentHashMap cache) throws Exception { Resource resourcesDir = null; if (cache != null && cache.containsKey(target)) { resourcesDir = cache.get(target); if (resourcesDir == EmptyResource.INSTANCE) { if (LOG.isDebugEnabled()) LOG.debug(target+" cached as containing no META-INF/resources"); return; } else if (LOG.isDebugEnabled()) LOG.debug(target+" META-INF/resources found in cache "); } else { //not using caches or not in the cache so check for the resources dir if (LOG.isDebugEnabled()) LOG.debug(target+" META-INF/resources checked"); if (target.isDirectory()) { //TODO think how to handle an unpacked jar file (eg for osgi) resourcesDir = target.addPath("/META-INF/resources"); } else { //Resource represents a packed jar URI uri = target.getURI(); resourcesDir = Resource.newResource("jar:"+uri+"!/META-INF/resources"); } if (!resourcesDir.exists() || !resourcesDir.isDirectory()) resourcesDir = EmptyResource.INSTANCE; if (cache != null) { Resource old = cache.putIfAbsent(target, resourcesDir); if (old != null) resourcesDir = old; else if (LOG.isDebugEnabled()) LOG.debug(target+" META-INF/resources cache updated"); } if (resourcesDir == EmptyResource.INSTANCE) return; } //add it to the meta inf resources for this context Set dirs = (Set)context.getAttribute(METAINF_RESOURCES); if (dirs == null) { dirs = new HashSet(); context.setAttribute(METAINF_RESOURCES, dirs); } if (LOG.isDebugEnabled()) LOG.debug(resourcesDir+" added to context"); dirs.add(resourcesDir); } /** * Scan for META-INF/web-fragment.xml file in the given jar. * * @param context * @param jar * @param cache * @throws Exception */ public void scanForFragment (WebAppContext context, Resource jar, ConcurrentHashMap cache) throws Exception { Resource webFrag = null; if (cache != null && cache.containsKey(jar)) { webFrag = cache.get(jar); if (webFrag == EmptyResource.INSTANCE) { if (LOG.isDebugEnabled()) LOG.debug(jar+" cached as containing no META-INF/web-fragment.xml"); return; } else if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/web-fragment.xml found in cache "); } else { //not using caches or not in the cache so check for the web-fragment.xml if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/web-fragment.xml checked"); if (jar.isDirectory()) { //TODO ???? webFrag = jar.addPath("/META-INF/web-fragment.xml"); } else { URI uri = jar.getURI(); webFrag = Resource.newResource("jar:"+uri+"!/META-INF/web-fragment.xml"); } if (!webFrag.exists() || webFrag.isDirectory()) webFrag = EmptyResource.INSTANCE; if (cache != null) { //web-fragment.xml doesn't exist: put token in cache to signal we've seen the jar Resource old = cache.putIfAbsent(jar, webFrag); if (old != null) webFrag = old; else if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/web-fragment.xml cache updated"); } if (webFrag == EmptyResource.INSTANCE) return; } Map fragments = (Map)context.getAttribute(METAINF_FRAGMENTS); if (fragments == null) { fragments = new HashMap(); context.setAttribute(METAINF_FRAGMENTS, fragments); } fragments.put(jar, webFrag); if (LOG.isDebugEnabled()) LOG.debug(webFrag+" added to context"); } /** * Discover META-INF/*.tld files in the given jar * * @param context * @param jar * @param cache * @throws Exception */ public void scanForTlds (WebAppContext context, Resource jar, ConcurrentHashMap> cache) throws Exception { Collection tlds = null; if (cache != null && cache.containsKey(jar)) { Collection tmp = cache.get(jar); if (tmp.isEmpty()) { if (LOG.isDebugEnabled()) LOG.debug(jar+" cached as containing no tlds"); return; } else { tlds = tmp; if (LOG.isDebugEnabled()) LOG.debug(jar+" tlds found in cache "); } } else { //not using caches or not in the cache so find all tlds Resource metaInfDir = null; if (jar.isDirectory()) { //TODO ?????? metaInfDir = jar.addPath("/META-INF/"); } else { URI uri = jar.getURI(); metaInfDir = Resource.newResource("jar:"+uri+"!/META-INF/"); } //find any *.tld files inside META-INF or subdirs tlds = new HashSet(); Collection resources = metaInfDir.getAllResources(); for (Resource t:resources) { String name = t.toString(); if (name.endsWith(".tld")) { if (LOG.isDebugEnabled()) LOG.debug(t+" tld discovered"); tlds.add(t.getURL()); } } if (cache != null) { if (LOG.isDebugEnabled()) LOG.debug(jar+" tld cache updated"); Collection old = (Collection)cache.putIfAbsent(jar, tlds); if (old != null) tlds = old; } if (tlds.isEmpty()) return; } Collection tld_resources=(Collection)context.getAttribute(METAINF_TLDS); if (tld_resources == null) { tld_resources = new HashSet(); context.setAttribute(METAINF_TLDS, tld_resources); } tld_resources.addAll(tlds); if (LOG.isDebugEnabled()) LOG.debug("tlds added to context"); } @Override public void postConfigure(WebAppContext context) throws Exception { context.setAttribute(METAINF_FRAGMENTS, null); context.setAttribute(METAINF_RESOURCES, null); context.setAttribute(METAINF_TLDS, null); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy