103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.webapp; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException; 2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.URI; 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.URL; 2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.ArrayList; 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Collection; 2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.EventListener; 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashMap; 2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashSet; 2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Iterator; 3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.List; 3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Locale; 3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Map; 3303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Set; 3403928aee4356845252ac6b662d5c72c29903813eJake Slack 3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.Servlet; 3603928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.ServletContextEvent; 3703928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.ServletContextListener; 3803928aee4356845252ac6b662d5c72c29903813eJake Slack 3903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.Loader; 4003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log; 4103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger; 4203928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.resource.Resource; 4303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.xml.XmlParser; 4403928aee4356845252ac6b662d5c72c29903813eJake Slack 4503928aee4356845252ac6b662d5c72c29903813eJake Slack/* ------------------------------------------------------------ */ 4603928aee4356845252ac6b662d5c72c29903813eJake Slack/** TagLibConfiguration. 4703928aee4356845252ac6b662d5c72c29903813eJake Slack * 4803928aee4356845252ac6b662d5c72c29903813eJake Slack * The class searches for TLD descriptors found in web.xml, in WEB-INF/*.tld files of the web app 4903928aee4356845252ac6b662d5c72c29903813eJake Slack * or *.tld files within jars found in WEB-INF/lib of the webapp. Any listeners defined in these 5003928aee4356845252ac6b662d5c72c29903813eJake Slack * tld's are added to the context. 5103928aee4356845252ac6b662d5c72c29903813eJake Slack * 5203928aee4356845252ac6b662d5c72c29903813eJake Slack * <bile>This is total rubbish special case for JSPs! If there was a general use-case for web app 5303928aee4356845252ac6b662d5c72c29903813eJake Slack * frameworks to register listeners directly, then a generic mechanism could have been added to the servlet 5403928aee4356845252ac6b662d5c72c29903813eJake Slack * spec. Instead some special purpose JSP support is required that breaks all sorts of encapsulation rules as 5503928aee4356845252ac6b662d5c72c29903813eJake Slack * the servlet container must go searching for and then parsing the descriptors for one particular framework. 5603928aee4356845252ac6b662d5c72c29903813eJake Slack * It only appears to be used by JSF, which is being developed by the same developer who implemented this 5703928aee4356845252ac6b662d5c72c29903813eJake Slack * feature in the first place! 5803928aee4356845252ac6b662d5c72c29903813eJake Slack * </bile> 5903928aee4356845252ac6b662d5c72c29903813eJake Slack * 6003928aee4356845252ac6b662d5c72c29903813eJake Slack * 6103928aee4356845252ac6b662d5c72c29903813eJake Slack * Note- this has been superceded by the new TldScanner in jasper which uses ServletContainerInitializer to 6203928aee4356845252ac6b662d5c72c29903813eJake Slack * find all the listeners in tag libs and register them. 6303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 6403928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class TagLibConfiguration extends AbstractConfiguration 6503928aee4356845252ac6b662d5c72c29903813eJake Slack{ 6603928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Logger LOG = Log.getLogger(TagLibConfiguration.class); 6703928aee4356845252ac6b662d5c72c29903813eJake Slack 6803928aee4356845252ac6b662d5c72c29903813eJake Slack public static final String TLD_RESOURCES = "org.eclipse.jetty.tlds"; 6903928aee4356845252ac6b662d5c72c29903813eJake Slack 7003928aee4356845252ac6b662d5c72c29903813eJake Slack 7103928aee4356845252ac6b662d5c72c29903813eJake Slack /** 7203928aee4356845252ac6b662d5c72c29903813eJake Slack * TagLibListener 7303928aee4356845252ac6b662d5c72c29903813eJake Slack * 7403928aee4356845252ac6b662d5c72c29903813eJake Slack * A listener that does the job of finding .tld files that contain 7503928aee4356845252ac6b662d5c72c29903813eJake Slack * (other) listeners that need to be called by the servlet container. 7603928aee4356845252ac6b662d5c72c29903813eJake Slack * 7703928aee4356845252ac6b662d5c72c29903813eJake Slack * This implementation is necessitated by the fact that it is only 7803928aee4356845252ac6b662d5c72c29903813eJake Slack * after all the Configuration classes have run that we will 7903928aee4356845252ac6b662d5c72c29903813eJake Slack * parse web.xml/fragments etc and thus find tlds mentioned therein. 8003928aee4356845252ac6b662d5c72c29903813eJake Slack * 8103928aee4356845252ac6b662d5c72c29903813eJake Slack * Note: TagLibConfiguration is not used in jetty-8 as jasper (JSP engine) 8203928aee4356845252ac6b662d5c72c29903813eJake Slack * uses the new TldScanner class - a ServletContainerInitializer from 8303928aee4356845252ac6b662d5c72c29903813eJake Slack * Servlet Spec 3 - to find all listeners in taglibs and register them 8403928aee4356845252ac6b662d5c72c29903813eJake Slack * with the servlet container. 8503928aee4356845252ac6b662d5c72c29903813eJake Slack */ 8603928aee4356845252ac6b662d5c72c29903813eJake Slack public class TagLibListener implements ServletContextListener { 8703928aee4356845252ac6b662d5c72c29903813eJake Slack private List<EventListener> _tldListeners; 8803928aee4356845252ac6b662d5c72c29903813eJake Slack private WebAppContext _context; 8903928aee4356845252ac6b662d5c72c29903813eJake Slack 9003928aee4356845252ac6b662d5c72c29903813eJake Slack public TagLibListener (WebAppContext context) { 9103928aee4356845252ac6b662d5c72c29903813eJake Slack _context = context; 9203928aee4356845252ac6b662d5c72c29903813eJake Slack } 9303928aee4356845252ac6b662d5c72c29903813eJake Slack 9403928aee4356845252ac6b662d5c72c29903813eJake Slack public void contextDestroyed(ServletContextEvent sce) 9503928aee4356845252ac6b662d5c72c29903813eJake Slack { 9603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_tldListeners == null) 9703928aee4356845252ac6b662d5c72c29903813eJake Slack return; 9803928aee4356845252ac6b662d5c72c29903813eJake Slack 9903928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=_tldListeners.size()-1; i>=0; i--) { 10003928aee4356845252ac6b662d5c72c29903813eJake Slack EventListener l = _tldListeners.get(i); 10103928aee4356845252ac6b662d5c72c29903813eJake Slack if (l instanceof ServletContextListener) { 10203928aee4356845252ac6b662d5c72c29903813eJake Slack ((ServletContextListener)l).contextDestroyed(sce); 10303928aee4356845252ac6b662d5c72c29903813eJake Slack } 10403928aee4356845252ac6b662d5c72c29903813eJake Slack } 10503928aee4356845252ac6b662d5c72c29903813eJake Slack } 10603928aee4356845252ac6b662d5c72c29903813eJake Slack 10703928aee4356845252ac6b662d5c72c29903813eJake Slack public void contextInitialized(ServletContextEvent sce) 10803928aee4356845252ac6b662d5c72c29903813eJake Slack { 10903928aee4356845252ac6b662d5c72c29903813eJake Slack try 11003928aee4356845252ac6b662d5c72c29903813eJake Slack { 11103928aee4356845252ac6b662d5c72c29903813eJake Slack //For jasper 2.1: 11203928aee4356845252ac6b662d5c72c29903813eJake Slack //Get the system classpath tlds and tell jasper about them, if jasper is on the classpath 11303928aee4356845252ac6b662d5c72c29903813eJake Slack try 11403928aee4356845252ac6b662d5c72c29903813eJake Slack { 11503928aee4356845252ac6b662d5c72c29903813eJake Slack 11603928aee4356845252ac6b662d5c72c29903813eJake Slack ClassLoader loader = _context.getClassLoader(); 11703928aee4356845252ac6b662d5c72c29903813eJake Slack if (loader == null || loader.getParent() == null) 11803928aee4356845252ac6b662d5c72c29903813eJake Slack loader = getClass().getClassLoader(); 11903928aee4356845252ac6b662d5c72c29903813eJake Slack else 12003928aee4356845252ac6b662d5c72c29903813eJake Slack loader = loader.getParent(); 12103928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> clazz = loader.loadClass("org.apache.jasper.compiler.TldLocationsCache"); 12203928aee4356845252ac6b662d5c72c29903813eJake Slack assert clazz!=null; 12303928aee4356845252ac6b662d5c72c29903813eJake Slack Collection<Resource> tld_resources = (Collection<Resource>)_context.getAttribute(TLD_RESOURCES); 12403928aee4356845252ac6b662d5c72c29903813eJake Slack 12503928aee4356845252ac6b662d5c72c29903813eJake Slack Map<URI, List<String>> tldMap = new HashMap<URI, List<String>>(); 12603928aee4356845252ac6b662d5c72c29903813eJake Slack 12703928aee4356845252ac6b662d5c72c29903813eJake Slack if (tld_resources != null) 12803928aee4356845252ac6b662d5c72c29903813eJake Slack { 12903928aee4356845252ac6b662d5c72c29903813eJake Slack //get the jar file names of the files 13003928aee4356845252ac6b662d5c72c29903813eJake Slack for (Resource r:tld_resources) 13103928aee4356845252ac6b662d5c72c29903813eJake Slack { 13203928aee4356845252ac6b662d5c72c29903813eJake Slack Resource jarResource = extractJarResource(r); 13303928aee4356845252ac6b662d5c72c29903813eJake Slack //jasper is happy with an empty list of tlds 13403928aee4356845252ac6b662d5c72c29903813eJake Slack if (!tldMap.containsKey(jarResource.getURI())) 13503928aee4356845252ac6b662d5c72c29903813eJake Slack tldMap.put(jarResource.getURI(), null); 13603928aee4356845252ac6b662d5c72c29903813eJake Slack 13703928aee4356845252ac6b662d5c72c29903813eJake Slack } 13803928aee4356845252ac6b662d5c72c29903813eJake Slack //set the magic context attribute that tells jasper about the system tlds 13903928aee4356845252ac6b662d5c72c29903813eJake Slack sce.getServletContext().setAttribute("com.sun.appserv.tld.map", tldMap); 14003928aee4356845252ac6b662d5c72c29903813eJake Slack } 14103928aee4356845252ac6b662d5c72c29903813eJake Slack } 14203928aee4356845252ac6b662d5c72c29903813eJake Slack catch (ClassNotFoundException e) 14303928aee4356845252ac6b662d5c72c29903813eJake Slack { 14403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 14503928aee4356845252ac6b662d5c72c29903813eJake Slack } 14603928aee4356845252ac6b662d5c72c29903813eJake Slack 14703928aee4356845252ac6b662d5c72c29903813eJake Slack //find the tld files and parse them to get out their 14803928aee4356845252ac6b662d5c72c29903813eJake Slack //listeners 14903928aee4356845252ac6b662d5c72c29903813eJake Slack Set<Resource> tlds = findTldResources(); 15003928aee4356845252ac6b662d5c72c29903813eJake Slack List<TldDescriptor> descriptors = parseTlds(tlds); 15103928aee4356845252ac6b662d5c72c29903813eJake Slack processTlds(descriptors); 15203928aee4356845252ac6b662d5c72c29903813eJake Slack 15303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_tldListeners == null) 15403928aee4356845252ac6b662d5c72c29903813eJake Slack return; 15503928aee4356845252ac6b662d5c72c29903813eJake Slack 15603928aee4356845252ac6b662d5c72c29903813eJake Slack //call the listeners that are ServletContextListeners, put the 15703928aee4356845252ac6b662d5c72c29903813eJake Slack //rest into the context's list of listeners to call at the appropriate 15803928aee4356845252ac6b662d5c72c29903813eJake Slack //moment 15903928aee4356845252ac6b662d5c72c29903813eJake Slack for (EventListener l:_tldListeners) { 16003928aee4356845252ac6b662d5c72c29903813eJake Slack if (l instanceof ServletContextListener) { 16103928aee4356845252ac6b662d5c72c29903813eJake Slack ((ServletContextListener)l).contextInitialized(sce); 16203928aee4356845252ac6b662d5c72c29903813eJake Slack } else { 16303928aee4356845252ac6b662d5c72c29903813eJake Slack _context.addEventListener(l); 16403928aee4356845252ac6b662d5c72c29903813eJake Slack } 16503928aee4356845252ac6b662d5c72c29903813eJake Slack } 16603928aee4356845252ac6b662d5c72c29903813eJake Slack 16703928aee4356845252ac6b662d5c72c29903813eJake Slack } 16803928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) { 16903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e); 17003928aee4356845252ac6b662d5c72c29903813eJake Slack } 17103928aee4356845252ac6b662d5c72c29903813eJake Slack } 17203928aee4356845252ac6b662d5c72c29903813eJake Slack 17303928aee4356845252ac6b662d5c72c29903813eJake Slack 17403928aee4356845252ac6b662d5c72c29903813eJake Slack 17503928aee4356845252ac6b662d5c72c29903813eJake Slack 17603928aee4356845252ac6b662d5c72c29903813eJake Slack private Resource extractJarResource (Resource r) 17703928aee4356845252ac6b662d5c72c29903813eJake Slack { 17803928aee4356845252ac6b662d5c72c29903813eJake Slack if (r == null) 17903928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 18003928aee4356845252ac6b662d5c72c29903813eJake Slack 18103928aee4356845252ac6b662d5c72c29903813eJake Slack try 18203928aee4356845252ac6b662d5c72c29903813eJake Slack { 18303928aee4356845252ac6b662d5c72c29903813eJake Slack String url = r.getURI().toURL().toString(); 18403928aee4356845252ac6b662d5c72c29903813eJake Slack int idx = url.lastIndexOf("!/"); 18503928aee4356845252ac6b662d5c72c29903813eJake Slack if (idx >= 0) 18603928aee4356845252ac6b662d5c72c29903813eJake Slack url = url.substring(0, idx); 18703928aee4356845252ac6b662d5c72c29903813eJake Slack if (url.startsWith("jar:")) 18803928aee4356845252ac6b662d5c72c29903813eJake Slack url = url.substring(4); 18903928aee4356845252ac6b662d5c72c29903813eJake Slack return Resource.newResource(url); 19003928aee4356845252ac6b662d5c72c29903813eJake Slack } 19103928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IOException e) 19203928aee4356845252ac6b662d5c72c29903813eJake Slack { 19303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e); 19403928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 19503928aee4356845252ac6b662d5c72c29903813eJake Slack } 19603928aee4356845252ac6b662d5c72c29903813eJake Slack } 19703928aee4356845252ac6b662d5c72c29903813eJake Slack 19803928aee4356845252ac6b662d5c72c29903813eJake Slack /** 19903928aee4356845252ac6b662d5c72c29903813eJake Slack * Find all the locations that can harbour tld files that may contain 20003928aee4356845252ac6b662d5c72c29903813eJake Slack * a listener which the web container is supposed to instantiate and 20103928aee4356845252ac6b662d5c72c29903813eJake Slack * call. 20203928aee4356845252ac6b662d5c72c29903813eJake Slack * 20303928aee4356845252ac6b662d5c72c29903813eJake Slack * @return 20403928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws IOException 20503928aee4356845252ac6b662d5c72c29903813eJake Slack */ 20603928aee4356845252ac6b662d5c72c29903813eJake Slack private Set<Resource> findTldResources () throws IOException { 20703928aee4356845252ac6b662d5c72c29903813eJake Slack 20803928aee4356845252ac6b662d5c72c29903813eJake Slack Set<Resource> tlds = new HashSet<Resource>(); 20903928aee4356845252ac6b662d5c72c29903813eJake Slack 21003928aee4356845252ac6b662d5c72c29903813eJake Slack // Find tld's from web.xml 21103928aee4356845252ac6b662d5c72c29903813eJake Slack // When web.xml was processed, it should have created aliases for all TLDs. So search resources aliases 21203928aee4356845252ac6b662d5c72c29903813eJake Slack // for aliases ending in tld 21303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_context.getResourceAliases()!=null && 21403928aee4356845252ac6b662d5c72c29903813eJake Slack _context.getBaseResource()!=null && 21503928aee4356845252ac6b662d5c72c29903813eJake Slack _context.getBaseResource().exists()) 21603928aee4356845252ac6b662d5c72c29903813eJake Slack { 21703928aee4356845252ac6b662d5c72c29903813eJake Slack Iterator<String> iter=_context.getResourceAliases().values().iterator(); 21803928aee4356845252ac6b662d5c72c29903813eJake Slack while(iter.hasNext()) 21903928aee4356845252ac6b662d5c72c29903813eJake Slack { 22003928aee4356845252ac6b662d5c72c29903813eJake Slack String location = iter.next(); 22103928aee4356845252ac6b662d5c72c29903813eJake Slack if (location!=null && location.toLowerCase(Locale.ENGLISH).endsWith(".tld")) 22203928aee4356845252ac6b662d5c72c29903813eJake Slack { 22303928aee4356845252ac6b662d5c72c29903813eJake Slack if (!location.startsWith("/")) 22403928aee4356845252ac6b662d5c72c29903813eJake Slack location="/WEB-INF/"+location; 22503928aee4356845252ac6b662d5c72c29903813eJake Slack Resource l=_context.getBaseResource().addPath(location); 22603928aee4356845252ac6b662d5c72c29903813eJake Slack tlds.add(l); 22703928aee4356845252ac6b662d5c72c29903813eJake Slack } 22803928aee4356845252ac6b662d5c72c29903813eJake Slack } 22903928aee4356845252ac6b662d5c72c29903813eJake Slack } 23003928aee4356845252ac6b662d5c72c29903813eJake Slack 23103928aee4356845252ac6b662d5c72c29903813eJake Slack // Look for any tlds in WEB-INF directly. 23203928aee4356845252ac6b662d5c72c29903813eJake Slack Resource web_inf = _context.getWebInf(); 23303928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_inf!=null) 23403928aee4356845252ac6b662d5c72c29903813eJake Slack { 23503928aee4356845252ac6b662d5c72c29903813eJake Slack String[] contents = web_inf.list(); 23603928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=0;contents!=null && i<contents.length;i++) 23703928aee4356845252ac6b662d5c72c29903813eJake Slack { 23803928aee4356845252ac6b662d5c72c29903813eJake Slack if (contents[i]!=null && contents[i].toLowerCase(Locale.ENGLISH).endsWith(".tld")) 23903928aee4356845252ac6b662d5c72c29903813eJake Slack { 24003928aee4356845252ac6b662d5c72c29903813eJake Slack Resource l=web_inf.addPath(contents[i]); 24103928aee4356845252ac6b662d5c72c29903813eJake Slack tlds.add(l); 24203928aee4356845252ac6b662d5c72c29903813eJake Slack } 24303928aee4356845252ac6b662d5c72c29903813eJake Slack } 24403928aee4356845252ac6b662d5c72c29903813eJake Slack } 24503928aee4356845252ac6b662d5c72c29903813eJake Slack 24603928aee4356845252ac6b662d5c72c29903813eJake Slack //Look for tlds in common location of WEB-INF/tlds 24703928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_inf != null) { 24803928aee4356845252ac6b662d5c72c29903813eJake Slack Resource web_inf_tlds = _context.getWebInf().addPath("/tlds/"); 24903928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_inf_tlds.exists() && web_inf_tlds.isDirectory()) { 25003928aee4356845252ac6b662d5c72c29903813eJake Slack String[] contents = web_inf_tlds.list(); 25103928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=0;contents!=null && i<contents.length;i++) 25203928aee4356845252ac6b662d5c72c29903813eJake Slack { 25303928aee4356845252ac6b662d5c72c29903813eJake Slack if (contents[i]!=null && contents[i].toLowerCase(Locale.ENGLISH).endsWith(".tld")) 25403928aee4356845252ac6b662d5c72c29903813eJake Slack { 25503928aee4356845252ac6b662d5c72c29903813eJake Slack Resource l=web_inf_tlds.addPath(contents[i]); 25603928aee4356845252ac6b662d5c72c29903813eJake Slack tlds.add(l); 25703928aee4356845252ac6b662d5c72c29903813eJake Slack } 25803928aee4356845252ac6b662d5c72c29903813eJake Slack } 25903928aee4356845252ac6b662d5c72c29903813eJake Slack } 26003928aee4356845252ac6b662d5c72c29903813eJake Slack } 26103928aee4356845252ac6b662d5c72c29903813eJake Slack 26203928aee4356845252ac6b662d5c72c29903813eJake Slack // Add in tlds found in META-INF of jars. The jars that will be scanned are controlled by 26303928aee4356845252ac6b662d5c72c29903813eJake Slack // the patterns defined in the context attributes: org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern, 26403928aee4356845252ac6b662d5c72c29903813eJake Slack // and org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern 26503928aee4356845252ac6b662d5c72c29903813eJake Slack @SuppressWarnings("unchecked") 26603928aee4356845252ac6b662d5c72c29903813eJake Slack Collection<Resource> tld_resources=(Collection<Resource>)_context.getAttribute(TLD_RESOURCES); 26703928aee4356845252ac6b662d5c72c29903813eJake Slack if (tld_resources!=null) 26803928aee4356845252ac6b662d5c72c29903813eJake Slack tlds.addAll(tld_resources); 26903928aee4356845252ac6b662d5c72c29903813eJake Slack 27003928aee4356845252ac6b662d5c72c29903813eJake Slack return tlds; 27103928aee4356845252ac6b662d5c72c29903813eJake Slack } 27203928aee4356845252ac6b662d5c72c29903813eJake Slack 27303928aee4356845252ac6b662d5c72c29903813eJake Slack 27403928aee4356845252ac6b662d5c72c29903813eJake Slack /** 27503928aee4356845252ac6b662d5c72c29903813eJake Slack * Parse xml into in-memory tree 27603928aee4356845252ac6b662d5c72c29903813eJake Slack * @param tlds 27703928aee4356845252ac6b662d5c72c29903813eJake Slack * @return 27803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 27903928aee4356845252ac6b662d5c72c29903813eJake Slack private List<TldDescriptor> parseTlds (Set<Resource> tlds) { 28003928aee4356845252ac6b662d5c72c29903813eJake Slack List<TldDescriptor> descriptors = new ArrayList<TldDescriptor>(); 28103928aee4356845252ac6b662d5c72c29903813eJake Slack 28203928aee4356845252ac6b662d5c72c29903813eJake Slack Resource tld = null; 28303928aee4356845252ac6b662d5c72c29903813eJake Slack Iterator<Resource> iter = tlds.iterator(); 28403928aee4356845252ac6b662d5c72c29903813eJake Slack while (iter.hasNext()) 28503928aee4356845252ac6b662d5c72c29903813eJake Slack { 28603928aee4356845252ac6b662d5c72c29903813eJake Slack try 28703928aee4356845252ac6b662d5c72c29903813eJake Slack { 28803928aee4356845252ac6b662d5c72c29903813eJake Slack tld = iter.next(); 28903928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) LOG.debug("TLD="+tld); 29003928aee4356845252ac6b662d5c72c29903813eJake Slack 29103928aee4356845252ac6b662d5c72c29903813eJake Slack TldDescriptor d = new TldDescriptor(tld); 29203928aee4356845252ac6b662d5c72c29903813eJake Slack d.parse(); 29303928aee4356845252ac6b662d5c72c29903813eJake Slack descriptors.add(d); 29403928aee4356845252ac6b662d5c72c29903813eJake Slack } 29503928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 29603928aee4356845252ac6b662d5c72c29903813eJake Slack { 29703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Unable to parse TLD: " + tld,e); 29803928aee4356845252ac6b662d5c72c29903813eJake Slack } 29903928aee4356845252ac6b662d5c72c29903813eJake Slack } 30003928aee4356845252ac6b662d5c72c29903813eJake Slack return descriptors; 30103928aee4356845252ac6b662d5c72c29903813eJake Slack } 30203928aee4356845252ac6b662d5c72c29903813eJake Slack 30303928aee4356845252ac6b662d5c72c29903813eJake Slack 30403928aee4356845252ac6b662d5c72c29903813eJake Slack /** 30503928aee4356845252ac6b662d5c72c29903813eJake Slack * Create listeners from the parsed tld trees 30603928aee4356845252ac6b662d5c72c29903813eJake Slack * @param descriptors 30703928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws Exception 30803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 30903928aee4356845252ac6b662d5c72c29903813eJake Slack private void processTlds (List<TldDescriptor> descriptors) throws Exception { 31003928aee4356845252ac6b662d5c72c29903813eJake Slack 31103928aee4356845252ac6b662d5c72c29903813eJake Slack TldProcessor processor = new TldProcessor(); 31203928aee4356845252ac6b662d5c72c29903813eJake Slack for (TldDescriptor d:descriptors) 31303928aee4356845252ac6b662d5c72c29903813eJake Slack processor.process(_context, d); 31403928aee4356845252ac6b662d5c72c29903813eJake Slack 31503928aee4356845252ac6b662d5c72c29903813eJake Slack _tldListeners = new ArrayList<EventListener>(processor.getListeners()); 31603928aee4356845252ac6b662d5c72c29903813eJake Slack } 31703928aee4356845252ac6b662d5c72c29903813eJake Slack } 31803928aee4356845252ac6b662d5c72c29903813eJake Slack 31903928aee4356845252ac6b662d5c72c29903813eJake Slack 32003928aee4356845252ac6b662d5c72c29903813eJake Slack 32103928aee4356845252ac6b662d5c72c29903813eJake Slack 32203928aee4356845252ac6b662d5c72c29903813eJake Slack /** 32303928aee4356845252ac6b662d5c72c29903813eJake Slack * TldDescriptor 32403928aee4356845252ac6b662d5c72c29903813eJake Slack * 32503928aee4356845252ac6b662d5c72c29903813eJake Slack * 32603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 32703928aee4356845252ac6b662d5c72c29903813eJake Slack public static class TldDescriptor extends Descriptor 32803928aee4356845252ac6b662d5c72c29903813eJake Slack { 32903928aee4356845252ac6b662d5c72c29903813eJake Slack protected static XmlParser __parserSingleton; 33003928aee4356845252ac6b662d5c72c29903813eJake Slack 33103928aee4356845252ac6b662d5c72c29903813eJake Slack public TldDescriptor(Resource xml) 33203928aee4356845252ac6b662d5c72c29903813eJake Slack { 33303928aee4356845252ac6b662d5c72c29903813eJake Slack super(xml); 33403928aee4356845252ac6b662d5c72c29903813eJake Slack } 33503928aee4356845252ac6b662d5c72c29903813eJake Slack 33603928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 33703928aee4356845252ac6b662d5c72c29903813eJake Slack public void ensureParser() throws ClassNotFoundException 33803928aee4356845252ac6b662d5c72c29903813eJake Slack { 33903928aee4356845252ac6b662d5c72c29903813eJake Slack if (__parserSingleton == null) 34003928aee4356845252ac6b662d5c72c29903813eJake Slack __parserSingleton = newParser(); 34103928aee4356845252ac6b662d5c72c29903813eJake Slack _parser = __parserSingleton; 34203928aee4356845252ac6b662d5c72c29903813eJake Slack } 34303928aee4356845252ac6b662d5c72c29903813eJake Slack 34403928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 34503928aee4356845252ac6b662d5c72c29903813eJake Slack public XmlParser newParser() throws ClassNotFoundException 34603928aee4356845252ac6b662d5c72c29903813eJake Slack { 34703928aee4356845252ac6b662d5c72c29903813eJake Slack // Create a TLD parser 34803928aee4356845252ac6b662d5c72c29903813eJake Slack XmlParser parser = new XmlParser(false); 34903928aee4356845252ac6b662d5c72c29903813eJake Slack 35003928aee4356845252ac6b662d5c72c29903813eJake Slack URL taglib11=null; 35103928aee4356845252ac6b662d5c72c29903813eJake Slack URL taglib12=null; 35203928aee4356845252ac6b662d5c72c29903813eJake Slack URL taglib20=null; 35303928aee4356845252ac6b662d5c72c29903813eJake Slack URL taglib21=null; 35403928aee4356845252ac6b662d5c72c29903813eJake Slack 35503928aee4356845252ac6b662d5c72c29903813eJake Slack try 35603928aee4356845252ac6b662d5c72c29903813eJake Slack { 35703928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> jsp_page = Loader.loadClass(WebXmlConfiguration.class,"javax.servlet.jsp.JspPage"); 35803928aee4356845252ac6b662d5c72c29903813eJake Slack taglib11=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd"); 35903928aee4356845252ac6b662d5c72c29903813eJake Slack taglib12=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd"); 36003928aee4356845252ac6b662d5c72c29903813eJake Slack taglib20=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd"); 36103928aee4356845252ac6b662d5c72c29903813eJake Slack taglib21=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd"); 36203928aee4356845252ac6b662d5c72c29903813eJake Slack } 36303928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 36403928aee4356845252ac6b662d5c72c29903813eJake Slack { 36503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 36603928aee4356845252ac6b662d5c72c29903813eJake Slack } 36703928aee4356845252ac6b662d5c72c29903813eJake Slack finally 36803928aee4356845252ac6b662d5c72c29903813eJake Slack { 36903928aee4356845252ac6b662d5c72c29903813eJake Slack if(taglib11==null) 37003928aee4356845252ac6b662d5c72c29903813eJake Slack taglib11=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd",true); 37103928aee4356845252ac6b662d5c72c29903813eJake Slack if(taglib12==null) 37203928aee4356845252ac6b662d5c72c29903813eJake Slack taglib12=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd",true); 37303928aee4356845252ac6b662d5c72c29903813eJake Slack if(taglib20==null) 37403928aee4356845252ac6b662d5c72c29903813eJake Slack taglib20=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd",true); 37503928aee4356845252ac6b662d5c72c29903813eJake Slack if(taglib21==null) 37603928aee4356845252ac6b662d5c72c29903813eJake Slack taglib21=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd",true); 37703928aee4356845252ac6b662d5c72c29903813eJake Slack } 37803928aee4356845252ac6b662d5c72c29903813eJake Slack 37903928aee4356845252ac6b662d5c72c29903813eJake Slack 38003928aee4356845252ac6b662d5c72c29903813eJake Slack if(taglib11!=null) 38103928aee4356845252ac6b662d5c72c29903813eJake Slack { 38203928aee4356845252ac6b662d5c72c29903813eJake Slack redirect(parser, "web-jsptaglib_1_1.dtd",taglib11); 38303928aee4356845252ac6b662d5c72c29903813eJake Slack redirect(parser, "web-jsptaglibrary_1_1.dtd",taglib11); 38403928aee4356845252ac6b662d5c72c29903813eJake Slack } 38503928aee4356845252ac6b662d5c72c29903813eJake Slack if(taglib12!=null) 38603928aee4356845252ac6b662d5c72c29903813eJake Slack { 38703928aee4356845252ac6b662d5c72c29903813eJake Slack redirect(parser, "web-jsptaglib_1_2.dtd",taglib12); 38803928aee4356845252ac6b662d5c72c29903813eJake Slack redirect(parser, "web-jsptaglibrary_1_2.dtd",taglib12); 38903928aee4356845252ac6b662d5c72c29903813eJake Slack } 39003928aee4356845252ac6b662d5c72c29903813eJake Slack if(taglib20!=null) 39103928aee4356845252ac6b662d5c72c29903813eJake Slack { 39203928aee4356845252ac6b662d5c72c29903813eJake Slack redirect(parser, "web-jsptaglib_2_0.xsd",taglib20); 39303928aee4356845252ac6b662d5c72c29903813eJake Slack redirect(parser, "web-jsptaglibrary_2_0.xsd",taglib20); 39403928aee4356845252ac6b662d5c72c29903813eJake Slack } 39503928aee4356845252ac6b662d5c72c29903813eJake Slack if(taglib21!=null) 39603928aee4356845252ac6b662d5c72c29903813eJake Slack { 39703928aee4356845252ac6b662d5c72c29903813eJake Slack redirect(parser, "web-jsptaglib_2_1.xsd",taglib21); 39803928aee4356845252ac6b662d5c72c29903813eJake Slack redirect(parser, "web-jsptaglibrary_2_1.xsd",taglib21); 39903928aee4356845252ac6b662d5c72c29903813eJake Slack } 40003928aee4356845252ac6b662d5c72c29903813eJake Slack 40103928aee4356845252ac6b662d5c72c29903813eJake Slack parser.setXpath("/taglib/listener/listener-class"); 40203928aee4356845252ac6b662d5c72c29903813eJake Slack return parser; 40303928aee4356845252ac6b662d5c72c29903813eJake Slack } 40403928aee4356845252ac6b662d5c72c29903813eJake Slack 40503928aee4356845252ac6b662d5c72c29903813eJake Slack public void parse () 40603928aee4356845252ac6b662d5c72c29903813eJake Slack throws Exception 40703928aee4356845252ac6b662d5c72c29903813eJake Slack { 40803928aee4356845252ac6b662d5c72c29903813eJake Slack ensureParser(); 40903928aee4356845252ac6b662d5c72c29903813eJake Slack try 41003928aee4356845252ac6b662d5c72c29903813eJake Slack { 41103928aee4356845252ac6b662d5c72c29903813eJake Slack //xerces on apple appears to sometimes close the zip file instead 41203928aee4356845252ac6b662d5c72c29903813eJake Slack //of the inputstream, so try opening the input stream, but if 41303928aee4356845252ac6b662d5c72c29903813eJake Slack //that doesn't work, fallback to opening a new url 41403928aee4356845252ac6b662d5c72c29903813eJake Slack _root = _parser.parse(_xml.getInputStream()); 41503928aee4356845252ac6b662d5c72c29903813eJake Slack } 41603928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 41703928aee4356845252ac6b662d5c72c29903813eJake Slack { 41803928aee4356845252ac6b662d5c72c29903813eJake Slack _root = _parser.parse(_xml.getURL().toString()); 41903928aee4356845252ac6b662d5c72c29903813eJake Slack } 42003928aee4356845252ac6b662d5c72c29903813eJake Slack 42103928aee4356845252ac6b662d5c72c29903813eJake Slack if (_root==null) 42203928aee4356845252ac6b662d5c72c29903813eJake Slack { 42303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("No TLD root in {}",_xml); 42403928aee4356845252ac6b662d5c72c29903813eJake Slack } 42503928aee4356845252ac6b662d5c72c29903813eJake Slack } 42603928aee4356845252ac6b662d5c72c29903813eJake Slack } 42703928aee4356845252ac6b662d5c72c29903813eJake Slack 42803928aee4356845252ac6b662d5c72c29903813eJake Slack 42903928aee4356845252ac6b662d5c72c29903813eJake Slack /** 43003928aee4356845252ac6b662d5c72c29903813eJake Slack * TldProcessor 43103928aee4356845252ac6b662d5c72c29903813eJake Slack * 43203928aee4356845252ac6b662d5c72c29903813eJake Slack * Process TldDescriptors representing tag libs to find listeners. 43303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 43403928aee4356845252ac6b662d5c72c29903813eJake Slack public class TldProcessor extends IterativeDescriptorProcessor 43503928aee4356845252ac6b662d5c72c29903813eJake Slack { 43603928aee4356845252ac6b662d5c72c29903813eJake Slack public static final String TAGLIB_PROCESSOR = "org.eclipse.jetty.tagLibProcessor"; 43703928aee4356845252ac6b662d5c72c29903813eJake Slack XmlParser _parser; 43803928aee4356845252ac6b662d5c72c29903813eJake Slack List<XmlParser.Node> _roots = new ArrayList<XmlParser.Node>(); 43903928aee4356845252ac6b662d5c72c29903813eJake Slack List<EventListener> _listeners; 44003928aee4356845252ac6b662d5c72c29903813eJake Slack 44103928aee4356845252ac6b662d5c72c29903813eJake Slack 44203928aee4356845252ac6b662d5c72c29903813eJake Slack public TldProcessor () 44303928aee4356845252ac6b662d5c72c29903813eJake Slack throws Exception 44403928aee4356845252ac6b662d5c72c29903813eJake Slack { 44503928aee4356845252ac6b662d5c72c29903813eJake Slack _listeners = new ArrayList<EventListener>(); 44603928aee4356845252ac6b662d5c72c29903813eJake Slack registerVisitor("listener", this.getClass().getDeclaredMethod("visitListener", __signature)); 44703928aee4356845252ac6b662d5c72c29903813eJake Slack } 44803928aee4356845252ac6b662d5c72c29903813eJake Slack 44903928aee4356845252ac6b662d5c72c29903813eJake Slack 45003928aee4356845252ac6b662d5c72c29903813eJake Slack public void visitListener (WebAppContext context, Descriptor descriptor, XmlParser.Node node) 45103928aee4356845252ac6b662d5c72c29903813eJake Slack { 45203928aee4356845252ac6b662d5c72c29903813eJake Slack String className=node.getString("listener-class",false,true); 45303928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 45403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("listener="+className); 45503928aee4356845252ac6b662d5c72c29903813eJake Slack 45603928aee4356845252ac6b662d5c72c29903813eJake Slack try 45703928aee4356845252ac6b662d5c72c29903813eJake Slack { 45803928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> listenerClass = context.loadClass(className); 45903928aee4356845252ac6b662d5c72c29903813eJake Slack EventListener l = (EventListener)listenerClass.newInstance(); 46003928aee4356845252ac6b662d5c72c29903813eJake Slack _listeners.add(l); 46103928aee4356845252ac6b662d5c72c29903813eJake Slack } 46203928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 46303928aee4356845252ac6b662d5c72c29903813eJake Slack { 46403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Could not instantiate listener "+className+": "+e); 46503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(e); 46603928aee4356845252ac6b662d5c72c29903813eJake Slack } 46703928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Error e) 46803928aee4356845252ac6b662d5c72c29903813eJake Slack { 46903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Could not instantiate listener "+className+": "+e); 47003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(e); 47103928aee4356845252ac6b662d5c72c29903813eJake Slack } 47203928aee4356845252ac6b662d5c72c29903813eJake Slack 47303928aee4356845252ac6b662d5c72c29903813eJake Slack } 47403928aee4356845252ac6b662d5c72c29903813eJake Slack 47503928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 47603928aee4356845252ac6b662d5c72c29903813eJake Slack public void end(WebAppContext context, Descriptor descriptor) 47703928aee4356845252ac6b662d5c72c29903813eJake Slack { 47803928aee4356845252ac6b662d5c72c29903813eJake Slack } 47903928aee4356845252ac6b662d5c72c29903813eJake Slack 48003928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 48103928aee4356845252ac6b662d5c72c29903813eJake Slack public void start(WebAppContext context, Descriptor descriptor) 48203928aee4356845252ac6b662d5c72c29903813eJake Slack { 48303928aee4356845252ac6b662d5c72c29903813eJake Slack } 48403928aee4356845252ac6b662d5c72c29903813eJake Slack 48503928aee4356845252ac6b662d5c72c29903813eJake Slack public List<EventListener> getListeners() { 48603928aee4356845252ac6b662d5c72c29903813eJake Slack return _listeners; 48703928aee4356845252ac6b662d5c72c29903813eJake Slack } 48803928aee4356845252ac6b662d5c72c29903813eJake Slack } 48903928aee4356845252ac6b662d5c72c29903813eJake Slack 49003928aee4356845252ac6b662d5c72c29903813eJake Slack 49103928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 49203928aee4356845252ac6b662d5c72c29903813eJake Slack public void preConfigure(WebAppContext context) throws Exception 49303928aee4356845252ac6b662d5c72c29903813eJake Slack { 49403928aee4356845252ac6b662d5c72c29903813eJake Slack try 49503928aee4356845252ac6b662d5c72c29903813eJake Slack { 49603928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> jsp_page = Loader.loadClass(WebXmlConfiguration.class,"javax.servlet.jsp.JspPage"); 49703928aee4356845252ac6b662d5c72c29903813eJake Slack } 49803928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 49903928aee4356845252ac6b662d5c72c29903813eJake Slack { 50003928aee4356845252ac6b662d5c72c29903813eJake Slack //no jsp available, don't parse TLDs 50103928aee4356845252ac6b662d5c72c29903813eJake Slack return; 50203928aee4356845252ac6b662d5c72c29903813eJake Slack } 50303928aee4356845252ac6b662d5c72c29903813eJake Slack 50403928aee4356845252ac6b662d5c72c29903813eJake Slack TagLibListener tagLibListener = new TagLibListener(context); 50503928aee4356845252ac6b662d5c72c29903813eJake Slack context.addEventListener(tagLibListener); 50603928aee4356845252ac6b662d5c72c29903813eJake Slack } 50703928aee4356845252ac6b662d5c72c29903813eJake Slack 50803928aee4356845252ac6b662d5c72c29903813eJake Slack 50903928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 51003928aee4356845252ac6b662d5c72c29903813eJake Slack public void configure (WebAppContext context) throws Exception 51103928aee4356845252ac6b662d5c72c29903813eJake Slack { 51203928aee4356845252ac6b662d5c72c29903813eJake Slack } 51303928aee4356845252ac6b662d5c72c29903813eJake Slack 51403928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 51503928aee4356845252ac6b662d5c72c29903813eJake Slack public void postConfigure(WebAppContext context) throws Exception 51603928aee4356845252ac6b662d5c72c29903813eJake Slack { 51703928aee4356845252ac6b662d5c72c29903813eJake Slack } 51803928aee4356845252ac6b662d5c72c29903813eJake Slack 51903928aee4356845252ac6b662d5c72c29903813eJake Slack 52003928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 52103928aee4356845252ac6b662d5c72c29903813eJake Slack public void cloneConfigure(WebAppContext template, WebAppContext context) throws Exception 52203928aee4356845252ac6b662d5c72c29903813eJake Slack { 52303928aee4356845252ac6b662d5c72c29903813eJake Slack } 52403928aee4356845252ac6b662d5c72c29903813eJake Slack 52503928aee4356845252ac6b662d5c72c29903813eJake Slack 52603928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 52703928aee4356845252ac6b662d5c72c29903813eJake Slack public void deconfigure(WebAppContext context) throws Exception 52803928aee4356845252ac6b662d5c72c29903813eJake Slack { 52903928aee4356845252ac6b662d5c72c29903813eJake Slack } 53003928aee4356845252ac6b662d5c72c29903813eJake Slack} 531